Fixes ACREP-30.
[mkws-moved-to-github.git] / tools / htdocs / releases / mkws-complete-1.0.0.min.js
1 /*! Copyright (c) 2013-2014 Index Data ApS. http://indexdata.com
2    Licence: LGPL, http://www.indexdata.com/licences/lgpl
3    created at: Tue Nov 11 13:25:11 GMT 2014
4    MKWS GIT id: b99a8c62ed342809871bdad8ec8890809ee0b726
5    pz2.js GIT id: 376322f0e5d56c9dcc23d0f7d15c90eb58342326
6 */
7 /*! jQuery v1.10.0 | (c) 2005, 2013 jQuery Foundation, Inc. | jquery.org/license
8 //@ 
9 */
10 (function(e,t){var n,r,i=typeof t,o=e.location,a=e.document,s=a.documentElement,l=e.jQuery,u=e.$,c={},p=[],f="1.10.0",d=p.concat,h=p.push,g=p.slice,m=p.indexOf,y=c.toString,v=c.hasOwnProperty,b=f.trim,x=function(e,t){return new x.fn.init(e,t,r)},w=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,T=/\S+/g,C=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,N=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,k=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,E=/^[\],:{}\s]*$/,S=/(?:^|:|,)(?:\s*\[)+/g,A=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,j=/"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g,D=/^-ms-/,L=/-([\da-z])/gi,H=function(e,t){return t.toUpperCase()},q=function(e){(a.addEventListener||"load"===e.type||"complete"===a.readyState)&&(_(),x.ready())},_=function(){a.addEventListener?(a.removeEventListener("DOMContentLoaded",q,!1),e.removeEventListener("load",q,!1)):(a.detachEvent("onreadystatechange",q),e.detachEvent("onload",q))};x.fn=x.prototype={jquery:f,constructor:x,init:function(e,n,r){var i,o;if(!e)return this;if("string"==typeof e){if(i="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:N.exec(e),!i||!i[1]&&n)return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e);if(i[1]){if(n=n instanceof x?n[0]:n,x.merge(this,x.parseHTML(i[1],n&&n.nodeType?n.ownerDocument||n:a,!0)),k.test(i[1])&&x.isPlainObject(n))for(i in n)x.isFunction(this[i])?this[i](n[i]):this.attr(i,n[i]);return this}if(o=a.getElementById(i[2]),o&&o.parentNode){if(o.id!==i[2])return r.find(e);this.length=1,this[0]=o}return this.context=a,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):x.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),x.makeArray(e,this))},selector:"",length:0,toArray:function(){return g.call(this)},get:function(e){return null==e?this.toArray():0>e?this[this.length+e]:this[e]},pushStack:function(e){var t=x.merge(this.constructor(),e);return t.prevObject=this,t.context=this.context,t},each:function(e,t){return x.each(this,e,t)},ready:function(e){return x.ready.promise().done(e),this},slice:function(){return this.pushStack(g.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(0>e?t:0);return this.pushStack(n>=0&&t>n?[this[n]]:[])},map:function(e){return this.pushStack(x.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:h,sort:[].sort,splice:[].splice},x.fn.init.prototype=x.fn,x.extend=x.fn.extend=function(){var e,n,r,i,o,a,s=arguments[0]||{},l=1,u=arguments.length,c=!1;for("boolean"==typeof s&&(c=s,s=arguments[1]||{},l=2),"object"==typeof s||x.isFunction(s)||(s={}),u===l&&(s=this,--l);u>l;l++)if(null!=(o=arguments[l]))for(i in o)e=s[i],r=o[i],s!==r&&(c&&r&&(x.isPlainObject(r)||(n=x.isArray(r)))?(n?(n=!1,a=e&&x.isArray(e)?e:[]):a=e&&x.isPlainObject(e)?e:{},s[i]=x.extend(c,a,r)):r!==t&&(s[i]=r));return s},x.extend({expando:"jQuery"+(f+Math.random()).replace(/\D/g,""),noConflict:function(t){return e.$===x&&(e.$=u),t&&e.jQuery===x&&(e.jQuery=l),x},isReady:!1,readyWait:1,holdReady:function(e){e?x.readyWait++:x.ready(!0)},ready:function(e){if(e===!0?!--x.readyWait:!x.isReady){if(!a.body)return setTimeout(x.ready);x.isReady=!0,e!==!0&&--x.readyWait>0||(n.resolveWith(a,[x]),x.fn.trigger&&x(a).trigger("ready").off("ready"))}},isFunction:function(e){return"function"===x.type(e)},isArray:Array.isArray||function(e){return"array"===x.type(e)},isWindow:function(e){return null!=e&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?c[y.call(e)]||"object":typeof e},isPlainObject:function(e){var n;if(!e||"object"!==x.type(e)||e.nodeType||x.isWindow(e))return!1;try{if(e.constructor&&!v.call(e,"constructor")&&!v.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(r){return!1}if(x.support.ownLast)for(n in e)return v.call(e,n);for(n in e);return n===t||v.call(e,n)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw Error(e)},parseHTML:function(e,t,n){if(!e||"string"!=typeof e)return null;"boolean"==typeof t&&(n=t,t=!1),t=t||a;var r=k.exec(e),i=!n&&[];return r?[t.createElement(r[1])]:(r=x.buildFragment([e],t,i),i&&x(i).remove(),x.merge([],r.childNodes))},parseJSON:function(n){return e.JSON&&e.JSON.parse?e.JSON.parse(n):null===n?n:"string"==typeof n&&(n=x.trim(n),n&&E.test(n.replace(A,"@").replace(j,"]").replace(S,"")))?Function("return "+n)():(x.error("Invalid JSON: "+n),t)},parseXML:function(n){var r,i;if(!n||"string"!=typeof n)return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(o){r=t}return r&&r.documentElement&&!r.getElementsByTagName("parsererror").length||x.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&x.trim(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(D,"ms-").replace(L,H)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t,n){var r,i=0,o=e.length,a=M(e);if(n){if(a){for(;o>i;i++)if(r=t.apply(e[i],n),r===!1)break}else for(i in e)if(r=t.apply(e[i],n),r===!1)break}else if(a){for(;o>i;i++)if(r=t.call(e[i],i,e[i]),r===!1)break}else for(i in e)if(r=t.call(e[i],i,e[i]),r===!1)break;return e},trim:b&&!b.call("\ufeff\u00a0")?function(e){return null==e?"":b.call(e)}:function(e){return null==e?"":(e+"").replace(C,"")},makeArray:function(e,t){var n=t||[];return null!=e&&(M(Object(e))?x.merge(n,"string"==typeof e?[e]:e):h.call(n,e)),n},inArray:function(e,t,n){var r;if(t){if(m)return m.call(t,e,n);for(r=t.length,n=n?0>n?Math.max(0,r+n):n:0;r>n;n++)if(n in t&&t[n]===e)return n}return-1},merge:function(e,n){var r=n.length,i=e.length,o=0;if("number"==typeof r)for(;r>o;o++)e[i++]=n[o];else while(n[o]!==t)e[i++]=n[o++];return e.length=i,e},grep:function(e,t,n){var r,i=[],o=0,a=e.length;for(n=!!n;a>o;o++)r=!!t(e[o],o),n!==r&&i.push(e[o]);return i},map:function(e,t,n){var r,i=0,o=e.length,a=M(e),s=[];if(a)for(;o>i;i++)r=t(e[i],i,n),null!=r&&(s[s.length]=r);else for(i in e)r=t(e[i],i,n),null!=r&&(s[s.length]=r);return d.apply([],s)},guid:1,proxy:function(e,n){var r,i,o;return"string"==typeof n&&(o=e[n],n=e,e=o),x.isFunction(e)?(r=g.call(arguments,2),i=function(){return e.apply(n||this,r.concat(g.call(arguments)))},i.guid=e.guid=e.guid||x.guid++,i):t},access:function(e,n,r,i,o,a,s){var l=0,u=e.length,c=null==r;if("object"===x.type(r)){o=!0;for(l in r)x.access(e,n,l,r[l],!0,a,s)}else if(i!==t&&(o=!0,x.isFunction(i)||(s=!0),c&&(s?(n.call(e,i),n=null):(c=n,n=function(e,t,n){return c.call(x(e),n)})),n))for(;u>l;l++)n(e[l],r,s?i:i.call(e[l],l,n(e[l],r)));return o?e:c?n.call(e):u?n(e[0],r):a},now:function(){return(new Date).getTime()},swap:function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=a[o];return i}}),x.ready.promise=function(t){if(!n)if(n=x.Deferred(),"complete"===a.readyState)setTimeout(x.ready);else if(a.addEventListener)a.addEventListener("DOMContentLoaded",q,!1),e.addEventListener("load",q,!1);else{a.attachEvent("onreadystatechange",q),e.attachEvent("onload",q);var r=!1;try{r=null==e.frameElement&&a.documentElement}catch(i){}r&&r.doScroll&&function o(){if(!x.isReady){try{r.doScroll("left")}catch(e){return setTimeout(o,50)}_(),x.ready()}}()}return n.promise(t)},x.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(e,t){c["[object "+t+"]"]=t.toLowerCase()});function M(e){var t=e.length,n=x.type(e);return x.isWindow(e)?!1:1===e.nodeType&&t?!0:"array"===n||"function"!==n&&(0===t||"number"==typeof t&&t>0&&t-1 in e)}r=x(a),function(e,t){var n,r,i,o,a,s,l,u,c,p,f,d,h,g,m,y,v,b="sizzle"+-new Date,w=e.document,T=0,C=0,N=lt(),k=lt(),E=lt(),S=!1,A=function(){return 0},j=typeof t,D=1<<31,L={}.hasOwnProperty,H=[],q=H.pop,_=H.push,M=H.push,O=H.slice,F=H.indexOf||function(e){var t=0,n=this.length;for(;n>t;t++)if(this[t]===e)return t;return-1},B="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",P="[\\x20\\t\\r\\n\\f]",R="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",W=R.replace("w","w#"),$="\\["+P+"*("+R+")"+P+"*(?:([*^$|!~]?=)"+P+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+W+")|)|)"+P+"*\\]",I=":("+R+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+$.replace(3,8)+")*)|.*)\\)|)",z=RegExp("^"+P+"+|((?:^|[^\\\\])(?:\\\\.)*)"+P+"+$","g"),X=RegExp("^"+P+"*,"+P+"*"),U=RegExp("^"+P+"*([>+~]|"+P+")"+P+"*"),V=RegExp(P+"*[+~]"),Y=RegExp("="+P+"*([^\\]'\"]*)"+P+"*\\]","g"),J=RegExp(I),G=RegExp("^"+W+"$"),Q={ID:RegExp("^#("+R+")"),CLASS:RegExp("^\\.("+R+")"),TAG:RegExp("^("+R.replace("w","w*")+")"),ATTR:RegExp("^"+$),PSEUDO:RegExp("^"+I),CHILD:RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+P+"*(even|odd|(([+-]|)(\\d*)n|)"+P+"*(?:([+-]|)"+P+"*(\\d+)|))"+P+"*\\)|)","i"),bool:RegExp("^(?:"+B+")$","i"),needsContext:RegExp("^"+P+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+P+"*((?:-\\d)?\\d*)"+P+"*\\)|)(?=[^-]|$)","i")},K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,et=/^(?:input|select|textarea|button)$/i,tt=/^h\d$/i,nt=/'|\\/g,rt=RegExp("\\\\([\\da-f]{1,6}"+P+"?|("+P+")|.)","ig"),it=function(e,t,n){var r="0x"+t-65536;return r!==r||n?t:0>r?String.fromCharCode(r+65536):String.fromCharCode(55296|r>>10,56320|1023&r)};try{M.apply(H=O.call(w.childNodes),w.childNodes),H[w.childNodes.length].nodeType}catch(ot){M={apply:H.length?function(e,t){_.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function at(e,t,n,i){var o,a,s,l,u,c,d,m,y,x;if((t?t.ownerDocument||t:w)!==f&&p(t),t=t||f,n=n||[],!e||"string"!=typeof e)return n;if(1!==(l=t.nodeType)&&9!==l)return[];if(h&&!i){if(o=Z.exec(e))if(s=o[1]){if(9===l){if(a=t.getElementById(s),!a||!a.parentNode)return n;if(a.id===s)return n.push(a),n}else if(t.ownerDocument&&(a=t.ownerDocument.getElementById(s))&&v(t,a)&&a.id===s)return n.push(a),n}else{if(o[2])return M.apply(n,t.getElementsByTagName(e)),n;if((s=o[3])&&r.getElementsByClassName&&t.getElementsByClassName)return M.apply(n,t.getElementsByClassName(s)),n}if(r.qsa&&(!g||!g.test(e))){if(m=d=b,y=t,x=9===l&&e,1===l&&"object"!==t.nodeName.toLowerCase()){c=bt(e),(d=t.getAttribute("id"))?m=d.replace(nt,"\\$&"):t.setAttribute("id",m),m="[id='"+m+"'] ",u=c.length;while(u--)c[u]=m+xt(c[u]);y=V.test(e)&&t.parentNode||t,x=c.join(",")}if(x)try{return M.apply(n,y.querySelectorAll(x)),n}catch(T){}finally{d||t.removeAttribute("id")}}}return At(e.replace(z,"$1"),t,n,i)}function st(e){return K.test(e+"")}function lt(){var e=[];function t(n,r){return e.push(n+=" ")>o.cacheLength&&delete t[e.shift()],t[n]=r}return t}function ut(e){return e[b]=!0,e}function ct(e){var t=f.createElement("div");try{return!!e(t)}catch(n){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function pt(e,t,n){e=e.split("|");var r,i=e.length,a=n?null:t;while(i--)(r=o.attrHandle[e[i]])&&r!==t||(o.attrHandle[e[i]]=a)}function ft(e,t){var n=e.getAttributeNode(t);return n&&n.specified?n.value:e[t]===!0?t.toLowerCase():null}function dt(e,t){return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}function ht(e){return"input"===e.nodeName.toLowerCase()?e.defaultValue:t}function gt(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&(~t.sourceIndex||D)-(~e.sourceIndex||D);if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function mt(e){return function(t){var n=t.nodeName.toLowerCase();return"input"===n&&t.type===e}}function yt(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function vt(e){return ut(function(t){return t=+t,ut(function(n,r){var i,o=e([],n.length,t),a=o.length;while(a--)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}s=at.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?"HTML"!==t.nodeName:!1},r=at.support={},p=at.setDocument=function(e){var n=e?e.ownerDocument||e:w;return n!==f&&9===n.nodeType&&n.documentElement?(f=n,d=n.documentElement,h=!s(n),r.attributes=ct(function(e){return e.innerHTML="<a href='#'></a>",pt("type|href|height|width",dt,"#"===e.firstChild.getAttribute("href")),pt(B,ft,null==e.getAttribute("disabled")),e.className="i",!e.getAttribute("className")}),r.input=ct(function(e){return e.innerHTML="<input>",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")}),pt("value",ht,r.attributes&&r.input),r.getElementsByTagName=ct(function(e){return e.appendChild(n.createComment("")),!e.getElementsByTagName("*").length}),r.getElementsByClassName=ct(function(e){return e.innerHTML="<div class='a'></div><div class='a i'></div>",e.firstChild.className="i",2===e.getElementsByClassName("i").length}),r.getById=ct(function(e){return d.appendChild(e).id=b,!n.getElementsByName||!n.getElementsByName(b).length}),r.getById?(o.find.ID=function(e,t){if(typeof t.getElementById!==j&&h){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},o.filter.ID=function(e){var t=e.replace(rt,it);return function(e){return e.getAttribute("id")===t}}):(delete o.find.ID,o.filter.ID=function(e){var t=e.replace(rt,it);return function(e){var n=typeof e.getAttributeNode!==j&&e.getAttributeNode("id");return n&&n.value===t}}),o.find.TAG=r.getElementsByTagName?function(e,n){return typeof n.getElementsByTagName!==j?n.getElementsByTagName(e):t}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},o.find.CLASS=r.getElementsByClassName&&function(e,n){return typeof n.getElementsByClassName!==j&&h?n.getElementsByClassName(e):t},m=[],g=[],(r.qsa=st(n.querySelectorAll))&&(ct(function(e){e.innerHTML="<select><option selected=''></option></select>",e.querySelectorAll("[selected]").length||g.push("\\["+P+"*(?:value|"+B+")"),e.querySelectorAll(":checked").length||g.push(":checked")}),ct(function(e){var t=n.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("t",""),e.querySelectorAll("[t^='']").length&&g.push("[*^$]="+P+"*(?:''|\"\")"),e.querySelectorAll(":enabled").length||g.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),g.push(",.*:")})),(r.matchesSelector=st(y=d.webkitMatchesSelector||d.mozMatchesSelector||d.oMatchesSelector||d.msMatchesSelector))&&ct(function(e){r.disconnectedMatch=y.call(e,"div"),y.call(e,"[s!='']:x"),m.push("!=",I)}),g=g.length&&RegExp(g.join("|")),m=m.length&&RegExp(m.join("|")),v=st(d.contains)||d.compareDocumentPosition?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},r.sortDetached=ct(function(e){return 1&e.compareDocumentPosition(n.createElement("div"))}),A=d.compareDocumentPosition?function(e,t){if(e===t)return S=!0,0;var i=t.compareDocumentPosition&&e.compareDocumentPosition&&e.compareDocumentPosition(t);return i?1&i||!r.sortDetached&&t.compareDocumentPosition(e)===i?e===n||v(w,e)?-1:t===n||v(w,t)?1:c?F.call(c,e)-F.call(c,t):0:4&i?-1:1:e.compareDocumentPosition?-1:1}:function(e,t){var r,i=0,o=e.parentNode,a=t.parentNode,s=[e],l=[t];if(e===t)return S=!0,0;if(!o||!a)return e===n?-1:t===n?1:o?-1:a?1:c?F.call(c,e)-F.call(c,t):0;if(o===a)return gt(e,t);r=e;while(r=r.parentNode)s.unshift(r);r=t;while(r=r.parentNode)l.unshift(r);while(s[i]===l[i])i++;return i?gt(s[i],l[i]):s[i]===w?-1:l[i]===w?1:0},n):f},at.matches=function(e,t){return at(e,null,null,t)},at.matchesSelector=function(e,t){if((e.ownerDocument||e)!==f&&p(e),t=t.replace(Y,"='$1']"),!(!r.matchesSelector||!h||m&&m.test(t)||g&&g.test(t)))try{var n=y.call(e,t);if(n||r.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(i){}return at(t,f,null,[e]).length>0},at.contains=function(e,t){return(e.ownerDocument||e)!==f&&p(e),v(e,t)},at.attr=function(e,n){(e.ownerDocument||e)!==f&&p(e);var i=o.attrHandle[n.toLowerCase()],a=i&&L.call(o.attrHandle,n.toLowerCase())?i(e,n,!h):t;return a===t?r.attributes||!h?e.getAttribute(n):(a=e.getAttributeNode(n))&&a.specified?a.value:null:a},at.error=function(e){throw Error("Syntax error, unrecognized expression: "+e)},at.uniqueSort=function(e){var t,n=[],i=0,o=0;if(S=!r.detectDuplicates,c=!r.sortStable&&e.slice(0),e.sort(A),S){while(t=e[o++])t===e[o]&&(i=n.push(o));while(i--)e.splice(n[i],1)}return e},a=at.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=a(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r];r++)n+=a(t);return n},o=at.selectors={cacheLength:50,createPseudo:ut,match:Q,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(rt,it),e[3]=(e[4]||e[5]||"").replace(rt,it),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||at.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&at.error(e[0]),e},PSEUDO:function(e){var n,r=!e[5]&&e[2];return Q.CHILD.test(e[0])?null:(e[3]&&e[4]!==t?e[2]=e[4]:r&&J.test(r)&&(n=bt(r,!0))&&(n=r.indexOf(")",r.length-n)-r.length)&&(e[0]=e[0].slice(0,n),e[2]=r.slice(0,n)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(rt,it).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=N[e+" "];return t||(t=RegExp("(^|"+P+")"+e+"("+P+"|$)"))&&N(e,function(e){return t.test("string"==typeof e.className&&e.className||typeof e.getAttribute!==j&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=at.attr(r,e);return null==i?"!="===t:t?(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i+" ").indexOf(n)>-1:"|="===t?i===n||i.slice(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,l){var u,c,p,f,d,h,g=o!==a?"nextSibling":"previousSibling",m=t.parentNode,y=s&&t.nodeName.toLowerCase(),v=!l&&!s;if(m){if(o){while(g){p=t;while(p=p[g])if(s?p.nodeName.toLowerCase()===y:1===p.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?m.firstChild:m.lastChild],a&&v){c=m[b]||(m[b]={}),u=c[e]||[],d=u[0]===T&&u[1],f=u[0]===T&&u[2],p=d&&m.childNodes[d];while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if(1===p.nodeType&&++f&&p===t){c[e]=[T,d,f];break}}else if(v&&(u=(t[b]||(t[b]={}))[e])&&u[0]===T)f=u[1];else while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if((s?p.nodeName.toLowerCase()===y:1===p.nodeType)&&++f&&(v&&((p[b]||(p[b]={}))[e]=[T,f]),p===t))break;return f-=i,f===r||0===f%r&&f/r>=0}}},PSEUDO:function(e,t){var n,r=o.pseudos[e]||o.setFilters[e.toLowerCase()]||at.error("unsupported pseudo: "+e);return r[b]?r(t):r.length>1?(n=[e,e,"",t],o.setFilters.hasOwnProperty(e.toLowerCase())?ut(function(e,n){var i,o=r(e,t),a=o.length;while(a--)i=F.call(e,o[a]),e[i]=!(n[i]=o[a])}):function(e){return r(e,0,n)}):r}},pseudos:{not:ut(function(e){var t=[],n=[],r=l(e.replace(z,"$1"));return r[b]?ut(function(e,t,n,i){var o,a=r(e,null,i,[]),s=e.length;while(s--)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),!n.pop()}}),has:ut(function(e){return function(t){return at(e,t).length>0}}),contains:ut(function(e){return function(t){return(t.textContent||t.innerText||a(t)).indexOf(e)>-1}}),lang:ut(function(e){return G.test(e||"")||at.error("unsupported lang: "+e),e=e.replace(rt,it).toLowerCase(),function(t){var n;do if(n=h?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return n=n.toLowerCase(),n===e||0===n.indexOf(e+"-");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===d},focus:function(e){return e===f.activeElement&&(!f.hasFocus||f.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeName>"@"||3===e.nodeType||4===e.nodeType)return!1;return!0},parent:function(e){return!o.pseudos.empty(e)},header:function(e){return tt.test(e.nodeName)},input:function(e){return et.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||t.toLowerCase()===e.type)},first:vt(function(){return[0]}),last:vt(function(e,t){return[t-1]}),eq:vt(function(e,t,n){return[0>n?n+t:n]}),even:vt(function(e,t){var n=0;for(;t>n;n+=2)e.push(n);return e}),odd:vt(function(e,t){var n=1;for(;t>n;n+=2)e.push(n);return e}),lt:vt(function(e,t,n){var r=0>n?n+t:n;for(;--r>=0;)e.push(r);return e}),gt:vt(function(e,t,n){var r=0>n?n+t:n;for(;t>++r;)e.push(r);return e})}};for(n in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})o.pseudos[n]=mt(n);for(n in{submit:!0,reset:!0})o.pseudos[n]=yt(n);function bt(e,t){var n,r,i,a,s,l,u,c=k[e+" "];if(c)return t?0:c.slice(0);s=e,l=[],u=o.preFilter;while(s){(!n||(r=X.exec(s)))&&(r&&(s=s.slice(r[0].length)||s),l.push(i=[])),n=!1,(r=U.exec(s))&&(n=r.shift(),i.push({value:n,type:r[0].replace(z," ")}),s=s.slice(n.length));for(a in o.filter)!(r=Q[a].exec(s))||u[a]&&!(r=u[a](r))||(n=r.shift(),i.push({value:n,type:a,matches:r}),s=s.slice(n.length));if(!n)break}return t?s.length:s?at.error(e):k(e,l).slice(0)}function xt(e){var t=0,n=e.length,r="";for(;n>t;t++)r+=e[t].value;return r}function wt(e,t,n){var r=t.dir,o=n&&"parentNode"===r,a=C++;return t.first?function(t,n,i){while(t=t[r])if(1===t.nodeType||o)return e(t,n,i)}:function(t,n,s){var l,u,c,p=T+" "+a;if(s){while(t=t[r])if((1===t.nodeType||o)&&e(t,n,s))return!0}else while(t=t[r])if(1===t.nodeType||o)if(c=t[b]||(t[b]={}),(u=c[r])&&u[0]===p){if((l=u[1])===!0||l===i)return l===!0}else if(u=c[r]=[p],u[1]=e(t,n,s)||i,u[1]===!0)return!0}}function Tt(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function Ct(e,t,n,r,i){var o,a=[],s=0,l=e.length,u=null!=t;for(;l>s;s++)(o=e[s])&&(!n||n(o,r,i))&&(a.push(o),u&&t.push(s));return a}function Nt(e,t,n,r,i,o){return r&&!r[b]&&(r=Nt(r)),i&&!i[b]&&(i=Nt(i,o)),ut(function(o,a,s,l){var u,c,p,f=[],d=[],h=a.length,g=o||St(t||"*",s.nodeType?[s]:s,[]),m=!e||!o&&t?g:Ct(g,f,e,s,l),y=n?i||(o?e:h||r)?[]:a:m;if(n&&n(m,y,s,l),r){u=Ct(y,d),r(u,[],s,l),c=u.length;while(c--)(p=u[c])&&(y[d[c]]=!(m[d[c]]=p))}if(o){if(i||e){if(i){u=[],c=y.length;while(c--)(p=y[c])&&u.push(m[c]=p);i(null,y=[],u,l)}c=y.length;while(c--)(p=y[c])&&(u=i?F.call(o,p):f[c])>-1&&(o[u]=!(a[u]=p))}}else y=Ct(y===a?y.splice(h,y.length):y),i?i(null,a,y,l):M.apply(a,y)})}function kt(e){var t,n,r,i=e.length,a=o.relative[e[0].type],s=a||o.relative[" "],l=a?1:0,c=wt(function(e){return e===t},s,!0),p=wt(function(e){return F.call(t,e)>-1},s,!0),f=[function(e,n,r){return!a&&(r||n!==u)||((t=n).nodeType?c(e,n,r):p(e,n,r))}];for(;i>l;l++)if(n=o.relative[e[l].type])f=[wt(Tt(f),n)];else{if(n=o.filter[e[l].type].apply(null,e[l].matches),n[b]){for(r=++l;i>r;r++)if(o.relative[e[r].type])break;return Nt(l>1&&Tt(f),l>1&&xt(e.slice(0,l-1).concat({value:" "===e[l-2].type?"*":""})).replace(z,"$1"),n,r>l&&kt(e.slice(l,r)),i>r&&kt(e=e.slice(r)),i>r&&xt(e))}f.push(n)}return Tt(f)}function Et(e,t){var n=0,r=t.length>0,a=e.length>0,s=function(s,l,c,p,d){var h,g,m,y=[],v=0,b="0",x=s&&[],w=null!=d,C=u,N=s||a&&o.find.TAG("*",d&&l.parentNode||l),k=T+=null==C?1:Math.random()||.1;for(w&&(u=l!==f&&l,i=n);null!=(h=N[b]);b++){if(a&&h){g=0;while(m=e[g++])if(m(h,l,c)){p.push(h);break}w&&(T=k,i=++n)}r&&((h=!m&&h)&&v--,s&&x.push(h))}if(v+=b,r&&b!==v){g=0;while(m=t[g++])m(x,y,l,c);if(s){if(v>0)while(b--)x[b]||y[b]||(y[b]=q.call(p));y=Ct(y)}M.apply(p,y),w&&!s&&y.length>0&&v+t.length>1&&at.uniqueSort(p)}return w&&(T=k,u=C),x};return r?ut(s):s}l=at.compile=function(e,t){var n,r=[],i=[],o=E[e+" "];if(!o){t||(t=bt(e)),n=t.length;while(n--)o=kt(t[n]),o[b]?r.push(o):i.push(o);o=E(e,Et(i,r))}return o};function St(e,t,n){var r=0,i=t.length;for(;i>r;r++)at(e,t[r],n);return n}function At(e,t,n,i){var a,s,u,c,p,f=bt(e);if(!i&&1===f.length){if(s=f[0]=f[0].slice(0),s.length>2&&"ID"===(u=s[0]).type&&r.getById&&9===t.nodeType&&h&&o.relative[s[1].type]){if(t=(o.find.ID(u.matches[0].replace(rt,it),t)||[])[0],!t)return n;e=e.slice(s.shift().value.length)}a=Q.needsContext.test(e)?0:s.length;while(a--){if(u=s[a],o.relative[c=u.type])break;if((p=o.find[c])&&(i=p(u.matches[0].replace(rt,it),V.test(s[0].type)&&t.parentNode||t))){if(s.splice(a,1),e=i.length&&xt(s),!e)return M.apply(n,i),n;break}}}return l(e,f)(i,t,!h,n,V.test(e)),n}o.pseudos.nth=o.pseudos.eq;function jt(){}jt.prototype=o.filters=o.pseudos,o.setFilters=new jt,r.sortStable=b.split("").sort(A).join("")===b,p(),[0,0].sort(A),r.detectDuplicates=S,x.find=at,x.expr=at.selectors,x.expr[":"]=x.expr.pseudos,x.unique=at.uniqueSort,x.text=at.getText,x.isXMLDoc=at.isXML,x.contains=at.contains}(e);var O={};function F(e){var t=O[e]={};return x.each(e.match(T)||[],function(e,n){t[n]=!0}),t}x.Callbacks=function(e){e="string"==typeof e?O[e]||F(e):x.extend({},e);var n,r,i,o,a,s,l=[],u=!e.once&&[],c=function(t){for(r=e.memory&&t,i=!0,a=s||0,s=0,o=l.length,n=!0;l&&o>a;a++)if(l[a].apply(t[0],t[1])===!1&&e.stopOnFalse){r=!1;break}n=!1,l&&(u?u.length&&c(u.shift()):r?l=[]:p.disable())},p={add:function(){if(l){var t=l.length;(function i(t){x.each(t,function(t,n){var r=x.type(n);"function"===r?e.unique&&p.has(n)||l.push(n):n&&n.length&&"string"!==r&&i(n)})})(arguments),n?o=l.length:r&&(s=t,c(r))}return this},remove:function(){return l&&x.each(arguments,function(e,t){var r;while((r=x.inArray(t,l,r))>-1)l.splice(r,1),n&&(o>=r&&o--,a>=r&&a--)}),this},has:function(e){return e?x.inArray(e,l)>-1:!(!l||!l.length)},empty:function(){return l=[],o=0,this},disable:function(){return l=u=r=t,this},disabled:function(){return!l},lock:function(){return u=t,r||p.disable(),this},locked:function(){return!u},fireWith:function(e,t){return t=t||[],t=[e,t.slice?t.slice():t],!l||i&&!u||(n?u.push(t):c(t)),this},fire:function(){return p.fireWith(this,arguments),this},fired:function(){return!!i}};return p},x.extend({Deferred:function(e){var t=[["resolve","done",x.Callbacks("once memory"),"resolved"],["reject","fail",x.Callbacks("once memory"),"rejected"],["notify","progress",x.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return x.Deferred(function(n){x.each(t,function(t,o){var a=o[0],s=x.isFunction(e[t])&&e[t];i[o[1]](function(){var e=s&&s.apply(this,arguments);e&&x.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[a+"With"](this===r?n.promise():this,s?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?x.extend(e,r):r}},i={};return r.pipe=r.then,x.each(t,function(e,o){var a=o[2],s=o[3];r[o[1]]=a.add,s&&a.add(function(){n=s},t[1^e][2].disable,t[2][2].lock),i[o[0]]=function(){return i[o[0]+"With"](this===i?r:this,arguments),this},i[o[0]+"With"]=a.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=g.call(arguments),r=n.length,i=1!==r||e&&x.isFunction(e.promise)?r:0,o=1===i?e:x.Deferred(),a=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?g.call(arguments):r,n===s?o.notifyWith(t,n):--i||o.resolveWith(t,n)}},s,l,u;if(r>1)for(s=Array(r),l=Array(r),u=Array(r);r>t;t++)n[t]&&x.isFunction(n[t].promise)?n[t].promise().done(a(t,u,n)).fail(o.reject).progress(a(t,l,s)):--i;return i||o.resolveWith(u,n),o.promise()}}),x.support=function(t){var n,r,o,s,l,u,c,p,f,d=a.createElement("div");if(d.setAttribute("className","t"),d.innerHTML="  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",n=d.getElementsByTagName("*")||[],r=d.getElementsByTagName("a")[0],!r||!r.style||!n.length)return t;s=a.createElement("select"),u=s.appendChild(a.createElement("option")),o=d.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t.getSetAttribute="t"!==d.className,t.leadingWhitespace=3===d.firstChild.nodeType,t.tbody=!d.getElementsByTagName("tbody").length,t.htmlSerialize=!!d.getElementsByTagName("link").length,t.style=/top/.test(r.getAttribute("style")),t.hrefNormalized="/a"===r.getAttribute("href"),t.opacity=/^0.5/.test(r.style.opacity),t.cssFloat=!!r.style.cssFloat,t.checkOn=!!o.value,t.optSelected=u.selected,t.enctype=!!a.createElement("form").enctype,t.html5Clone="<:nav></:nav>"!==a.createElement("nav").cloneNode(!0).outerHTML,t.inlineBlockNeedsLayout=!1,t.shrinkWrapBlocks=!1,t.pixelPosition=!1,t.deleteExpando=!0,t.noCloneEvent=!0,t.reliableMarginRight=!0,t.boxSizingReliable=!0,o.checked=!0,t.noCloneChecked=o.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!u.disabled;try{delete d.test}catch(h){t.deleteExpando=!1}o=a.createElement("input"),o.setAttribute("value",""),t.input=""===o.getAttribute("value"),o.value="t",o.setAttribute("type","radio"),t.radioValue="t"===o.value,o.setAttribute("checked","t"),o.setAttribute("name","t"),l=a.createDocumentFragment(),l.appendChild(o),t.appendChecked=o.checked,t.checkClone=l.cloneNode(!0).cloneNode(!0).lastChild.checked,d.attachEvent&&(d.attachEvent("onclick",function(){t.noCloneEvent=!1}),d.cloneNode(!0).click());for(f in{submit:!0,change:!0,focusin:!0})d.setAttribute(c="on"+f,"t"),t[f+"Bubbles"]=c in e||d.attributes[c].expando===!1;d.style.backgroundClip="content-box",d.cloneNode(!0).style.backgroundClip="",t.clearCloneStyle="content-box"===d.style.backgroundClip;for(f in x(t))break;return t.ownLast="0"!==f,x(function(){var n,r,o,s="padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;",l=a.getElementsByTagName("body")[0];l&&(n=a.createElement("div"),n.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",l.appendChild(n).appendChild(d),d.innerHTML="<table><tr><td></td><td>t</td></tr></table>",o=d.getElementsByTagName("td"),o[0].style.cssText="padding:0;margin:0;border:0;display:none",p=0===o[0].offsetHeight,o[0].style.display="",o[1].style.display="none",t.reliableHiddenOffsets=p&&0===o[0].offsetHeight,d.innerHTML="",d.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",x.swap(l,null!=l.style.zoom?{zoom:1}:{},function(){t.boxSizing=4===d.offsetWidth}),e.getComputedStyle&&(t.pixelPosition="1%"!==(e.getComputedStyle(d,null)||{}).top,t.boxSizingReliable="4px"===(e.getComputedStyle(d,null)||{width:"4px"}).width,r=d.appendChild(a.createElement("div")),r.style.cssText=d.style.cssText=s,r.style.marginRight=r.style.width="0",d.style.width="1px",t.reliableMarginRight=!parseFloat((e.getComputedStyle(r,null)||{}).marginRight)),typeof d.style.zoom!==i&&(d.innerHTML="",d.style.cssText=s+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=3===d.offsetWidth,d.style.display="block",d.innerHTML="<div></div>",d.firstChild.style.width="5px",t.shrinkWrapBlocks=3!==d.offsetWidth,t.inlineBlockNeedsLayout&&(l.style.zoom=1)),l.removeChild(n),n=d=o=r=null)}),n=s=l=u=r=o=null,t}({});var B=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,P=/([A-Z])/g;function R(e,n,r,i){if(x.acceptData(e)){var o,a,s=x.expando,l=e.nodeType,u=l?x.cache:e,c=l?e[s]:e[s]&&s;
11 if(c&&u[c]&&(i||u[c].data)||r!==t||"string"!=typeof n)return c||(c=l?e[s]=p.pop()||x.guid++:s),u[c]||(u[c]=l?{}:{toJSON:x.noop}),("object"==typeof n||"function"==typeof n)&&(i?u[c]=x.extend(u[c],n):u[c].data=x.extend(u[c].data,n)),a=u[c],i||(a.data||(a.data={}),a=a.data),r!==t&&(a[x.camelCase(n)]=r),"string"==typeof n?(o=a[n],null==o&&(o=a[x.camelCase(n)])):o=a,o}}function W(e,t,n){if(x.acceptData(e)){var r,i,o=e.nodeType,a=o?x.cache:e,s=o?e[x.expando]:x.expando;if(a[s]){if(t&&(r=n?a[s]:a[s].data)){x.isArray(t)?t=t.concat(x.map(t,x.camelCase)):t in r?t=[t]:(t=x.camelCase(t),t=t in r?[t]:t.split(" ")),i=t.length;while(i--)delete r[t[i]];if(n?!I(r):!x.isEmptyObject(r))return}(n||(delete a[s].data,I(a[s])))&&(o?x.cleanData([e],!0):x.support.deleteExpando||a!=a.window?delete a[s]:a[s]=null)}}}x.extend({cache:{},noData:{applet:!0,embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(e){return e=e.nodeType?x.cache[e[x.expando]]:e[x.expando],!!e&&!I(e)},data:function(e,t,n){return R(e,t,n)},removeData:function(e,t){return W(e,t)},_data:function(e,t,n){return R(e,t,n,!0)},_removeData:function(e,t){return W(e,t,!0)},acceptData:function(e){if(e.nodeType&&1!==e.nodeType&&9!==e.nodeType)return!1;var t=e.nodeName&&x.noData[e.nodeName.toLowerCase()];return!t||t!==!0&&e.getAttribute("classid")===t}}),x.fn.extend({data:function(e,n){var r,i,o=null,a=0,s=this[0];if(e===t){if(this.length&&(o=x.data(s),1===s.nodeType&&!x._data(s,"parsedAttrs"))){for(r=s.attributes;r.length>a;a++)i=r[a].name,0===i.indexOf("data-")&&(i=x.camelCase(i.slice(5)),$(s,i,o[i]));x._data(s,"parsedAttrs",!0)}return o}return"object"==typeof e?this.each(function(){x.data(this,e)}):arguments.length>1?this.each(function(){x.data(this,e,n)}):s?$(s,e,x.data(s,e)):null},removeData:function(e){return this.each(function(){x.removeData(this,e)})}});function $(e,n,r){if(r===t&&1===e.nodeType){var i="data-"+n.replace(P,"-$1").toLowerCase();if(r=e.getAttribute(i),"string"==typeof r){try{r="true"===r?!0:"false"===r?!1:"null"===r?null:+r+""===r?+r:B.test(r)?x.parseJSON(r):r}catch(o){}x.data(e,n,r)}else r=t}return r}function I(e){var t;for(t in e)if(("data"!==t||!x.isEmptyObject(e[t]))&&"toJSON"!==t)return!1;return!0}x.extend({queue:function(e,n,r){var i;return e?(n=(n||"fx")+"queue",i=x._data(e,n),r&&(!i||x.isArray(r)?i=x._data(e,n,x.makeArray(r)):i.push(r)),i||[]):t},dequeue:function(e,t){t=t||"fx";var n=x.queue(e,t),r=n.length,i=n.shift(),o=x._queueHooks(e,t),a=function(){x.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),o.cur=i,i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return x._data(e,n)||x._data(e,n,{empty:x.Callbacks("once memory").add(function(){x._removeData(e,t+"queue"),x._removeData(e,n)})})}}),x.fn.extend({queue:function(e,n){var r=2;return"string"!=typeof e&&(n=e,e="fx",r--),r>arguments.length?x.queue(this[0],e):n===t?this:this.each(function(){var t=x.queue(this,e,n);x._queueHooks(this,e),"fx"===e&&"inprogress"!==t[0]&&x.dequeue(this,e)})},dequeue:function(e){return this.each(function(){x.dequeue(this,e)})},delay:function(e,t){return e=x.fx?x.fx.speeds[e]||e:e,t=t||"fx",this.queue(t,function(t,n){var r=setTimeout(t,e);n.stop=function(){clearTimeout(r)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,n){var r,i=1,o=x.Deferred(),a=this,s=this.length,l=function(){--i||o.resolveWith(a,[a])};"string"!=typeof e&&(n=e,e=t),e=e||"fx";while(s--)r=x._data(a[s],e+"queueHooks"),r&&r.empty&&(i++,r.empty.add(l));return l(),o.promise(n)}});var z,X,U=/[\t\r\n\f]/g,V=/\r/g,Y=/^(?:input|select|textarea|button|object)$/i,J=/^(?:a|area)$/i,G=/^(?:checked|selected)$/i,Q=x.support.getSetAttribute,K=x.support.input;x.fn.extend({attr:function(e,t){return x.access(this,x.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){x.removeAttr(this,e)})},prop:function(e,t){return x.access(this,x.prop,e,t,arguments.length>1)},removeProp:function(e){return e=x.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,o,a=0,s=this.length,l="string"==typeof e&&e;if(x.isFunction(e))return this.each(function(t){x(this).addClass(e.call(this,t,this.className))});if(l)for(t=(e||"").match(T)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(U," "):" ")){o=0;while(i=t[o++])0>r.indexOf(" "+i+" ")&&(r+=i+" ");n.className=x.trim(r)}return this},removeClass:function(e){var t,n,r,i,o,a=0,s=this.length,l=0===arguments.length||"string"==typeof e&&e;if(x.isFunction(e))return this.each(function(t){x(this).removeClass(e.call(this,t,this.className))});if(l)for(t=(e||"").match(T)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(U," "):"")){o=0;while(i=t[o++])while(r.indexOf(" "+i+" ")>=0)r=r.replace(" "+i+" "," ");n.className=e?x.trim(r):""}return this},toggleClass:function(e,t){var n=typeof e,r="boolean"==typeof t;return x.isFunction(e)?this.each(function(n){x(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if("string"===n){var o,a=0,s=x(this),l=t,u=e.match(T)||[];while(o=u[a++])l=r?l:!s.hasClass(o),s[l?"addClass":"removeClass"](o)}else(n===i||"boolean"===n)&&(this.className&&x._data(this,"__className__",this.className),this.className=this.className||e===!1?"":x._data(this,"__className__")||"")})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;r>n;n++)if(1===this[n].nodeType&&(" "+this[n].className+" ").replace(U," ").indexOf(t)>=0)return!0;return!1},val:function(e){var n,r,i,o=this[0];{if(arguments.length)return i=x.isFunction(e),this.each(function(n){var o;1===this.nodeType&&(o=i?e.call(this,n,x(this).val()):e,null==o?o="":"number"==typeof o?o+="":x.isArray(o)&&(o=x.map(o,function(e){return null==e?"":e+""})),r=x.valHooks[this.type]||x.valHooks[this.nodeName.toLowerCase()],r&&"set"in r&&r.set(this,o,"value")!==t||(this.value=o))});if(o)return r=x.valHooks[o.type]||x.valHooks[o.nodeName.toLowerCase()],r&&"get"in r&&(n=r.get(o,"value"))!==t?n:(n=o.value,"string"==typeof n?n.replace(V,""):null==n?"":n)}}}),x.extend({valHooks:{option:{get:function(e){var t=x.find.attr(e,"value");return null!=t?t:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,o="select-one"===e.type||0>i,a=o?null:[],s=o?i+1:r.length,l=0>i?s:o?i:0;for(;s>l;l++)if(n=r[l],!(!n.selected&&l!==i||(x.support.optDisabled?n.disabled:null!==n.getAttribute("disabled"))||n.parentNode.disabled&&x.nodeName(n.parentNode,"optgroup"))){if(t=x(n).val(),o)return t;a.push(t)}return a},set:function(e,t){var n,r,i=e.options,o=x.makeArray(t),a=i.length;while(a--)r=i[a],(r.selected=x.inArray(x(r).val(),o)>=0)&&(n=!0);return n||(e.selectedIndex=-1),o}}},attr:function(e,n,r){var o,a,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return typeof e.getAttribute===i?x.prop(e,n,r):(1===s&&x.isXMLDoc(e)||(n=n.toLowerCase(),o=x.attrHooks[n]||(x.expr.match.bool.test(n)?X:z)),r===t?o&&"get"in o&&null!==(a=o.get(e,n))?a:(a=x.find.attr(e,n),null==a?t:a):null!==r?o&&"set"in o&&(a=o.set(e,r,n))!==t?a:(e.setAttribute(n,r+""),r):(x.removeAttr(e,n),t))},removeAttr:function(e,t){var n,r,i=0,o=t&&t.match(T);if(o&&1===e.nodeType)while(n=o[i++])r=x.propFix[n]||n,x.expr.match.bool.test(n)?K&&Q||!G.test(n)?e[r]=!1:e[x.camelCase("default-"+n)]=e[r]=!1:x.attr(e,n,""),e.removeAttribute(Q?n:r)},attrHooks:{type:{set:function(e,t){if(!x.support.radioValue&&"radio"===t&&x.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},propFix:{"for":"htmlFor","class":"className"},prop:function(e,n,r){var i,o,a,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return a=1!==s||!x.isXMLDoc(e),a&&(n=x.propFix[n]||n,o=x.propHooks[n]),r!==t?o&&"set"in o&&(i=o.set(e,r,n))!==t?i:e[n]=r:o&&"get"in o&&null!==(i=o.get(e,n))?i:e[n]},propHooks:{tabIndex:{get:function(e){var t=x.find.attr(e,"tabindex");return t?parseInt(t,10):Y.test(e.nodeName)||J.test(e.nodeName)&&e.href?0:-1}}}}),X={set:function(e,t,n){return t===!1?x.removeAttr(e,n):K&&Q||!G.test(n)?e.setAttribute(!Q&&x.propFix[n]||n,n):e[x.camelCase("default-"+n)]=e[n]=!0,n}},x.each(x.expr.match.bool.source.match(/\w+/g),function(e,n){var r=x.expr.attrHandle[n]||x.find.attr;x.expr.attrHandle[n]=K&&Q||!G.test(n)?function(e,n,i){var o=x.expr.attrHandle[n],a=i?t:(x.expr.attrHandle[n]=t)!=r(e,n,i)?n.toLowerCase():null;return x.expr.attrHandle[n]=o,a}:function(e,n,r){return r?t:e[x.camelCase("default-"+n)]?n.toLowerCase():null}}),K&&Q||(x.attrHooks.value={set:function(e,n,r){return x.nodeName(e,"input")?(e.defaultValue=n,t):z&&z.set(e,n,r)}}),Q||(z={set:function(e,n,r){var i=e.getAttributeNode(r);return i||e.setAttributeNode(i=e.ownerDocument.createAttribute(r)),i.value=n+="","value"===r||n===e.getAttribute(r)?n:t}},x.expr.attrHandle.id=x.expr.attrHandle.name=x.expr.attrHandle.coords=function(e,n,r){var i;return r?t:(i=e.getAttributeNode(n))&&""!==i.value?i.value:null},x.valHooks.button={get:function(e,n){var r=e.getAttributeNode(n);return r&&r.specified?r.value:t},set:z.set},x.attrHooks.contenteditable={set:function(e,t,n){z.set(e,""===t?!1:t,n)}},x.each(["width","height"],function(e,n){x.attrHooks[n]={set:function(e,r){return""===r?(e.setAttribute(n,"auto"),r):t}}})),x.support.hrefNormalized||x.each(["href","src"],function(e,t){x.propHooks[t]={get:function(e){return e.getAttribute(t,4)}}}),x.support.style||(x.attrHooks.style={get:function(e){return e.style.cssText||t},set:function(e,t){return e.style.cssText=t+""}}),x.support.optSelected||(x.propHooks.selected={get:function(e){var t=e.parentNode;return t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex),null}}),x.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){x.propFix[this.toLowerCase()]=this}),x.support.enctype||(x.propFix.enctype="encoding"),x.each(["radio","checkbox"],function(){x.valHooks[this]={set:function(e,n){return x.isArray(n)?e.checked=x.inArray(x(e).val(),n)>=0:t}},x.support.checkOn||(x.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})});var Z=/^(?:input|select|textarea)$/i,et=/^key/,tt=/^(?:mouse|contextmenu)|click/,nt=/^(?:focusinfocus|focusoutblur)$/,rt=/^([^.]*)(?:\.(.+)|)$/;function it(){return!0}function ot(){return!1}function at(){try{return a.activeElement}catch(e){}}x.event={global:{},add:function(e,n,r,o,a){var s,l,u,c,p,f,d,h,g,m,y,v=x._data(e);if(v){r.handler&&(c=r,r=c.handler,a=c.selector),r.guid||(r.guid=x.guid++),(l=v.events)||(l=v.events={}),(f=v.handle)||(f=v.handle=function(e){return typeof x===i||e&&x.event.triggered===e.type?t:x.event.dispatch.apply(f.elem,arguments)},f.elem=e),n=(n||"").match(T)||[""],u=n.length;while(u--)s=rt.exec(n[u])||[],g=y=s[1],m=(s[2]||"").split(".").sort(),g&&(p=x.event.special[g]||{},g=(a?p.delegateType:p.bindType)||g,p=x.event.special[g]||{},d=x.extend({type:g,origType:y,data:o,handler:r,guid:r.guid,selector:a,needsContext:a&&x.expr.match.needsContext.test(a),namespace:m.join(".")},c),(h=l[g])||(h=l[g]=[],h.delegateCount=0,p.setup&&p.setup.call(e,o,m,f)!==!1||(e.addEventListener?e.addEventListener(g,f,!1):e.attachEvent&&e.attachEvent("on"+g,f))),p.add&&(p.add.call(e,d),d.handler.guid||(d.handler.guid=r.guid)),a?h.splice(h.delegateCount++,0,d):h.push(d),x.event.global[g]=!0);e=null}},remove:function(e,t,n,r,i){var o,a,s,l,u,c,p,f,d,h,g,m=x.hasData(e)&&x._data(e);if(m&&(c=m.events)){t=(t||"").match(T)||[""],u=t.length;while(u--)if(s=rt.exec(t[u])||[],d=g=s[1],h=(s[2]||"").split(".").sort(),d){p=x.event.special[d]||{},d=(r?p.delegateType:p.bindType)||d,f=c[d]||[],s=s[2]&&RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),l=o=f.length;while(o--)a=f[o],!i&&g!==a.origType||n&&n.guid!==a.guid||s&&!s.test(a.namespace)||r&&r!==a.selector&&("**"!==r||!a.selector)||(f.splice(o,1),a.selector&&f.delegateCount--,p.remove&&p.remove.call(e,a));l&&!f.length&&(p.teardown&&p.teardown.call(e,h,m.handle)!==!1||x.removeEvent(e,d,m.handle),delete c[d])}else for(d in c)x.event.remove(e,d+t[u],n,r,!0);x.isEmptyObject(c)&&(delete m.handle,x._removeData(e,"events"))}},trigger:function(n,r,i,o){var s,l,u,c,p,f,d,h=[i||a],g=v.call(n,"type")?n.type:n,m=v.call(n,"namespace")?n.namespace.split("."):[];if(u=f=i=i||a,3!==i.nodeType&&8!==i.nodeType&&!nt.test(g+x.event.triggered)&&(g.indexOf(".")>=0&&(m=g.split("."),g=m.shift(),m.sort()),l=0>g.indexOf(":")&&"on"+g,n=n[x.expando]?n:new x.Event(g,"object"==typeof n&&n),n.isTrigger=o?2:3,n.namespace=m.join("."),n.namespace_re=n.namespace?RegExp("(^|\\.)"+m.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,n.result=t,n.target||(n.target=i),r=null==r?[n]:x.makeArray(r,[n]),p=x.event.special[g]||{},o||!p.trigger||p.trigger.apply(i,r)!==!1)){if(!o&&!p.noBubble&&!x.isWindow(i)){for(c=p.delegateType||g,nt.test(c+g)||(u=u.parentNode);u;u=u.parentNode)h.push(u),f=u;f===(i.ownerDocument||a)&&h.push(f.defaultView||f.parentWindow||e)}d=0;while((u=h[d++])&&!n.isPropagationStopped())n.type=d>1?c:p.bindType||g,s=(x._data(u,"events")||{})[n.type]&&x._data(u,"handle"),s&&s.apply(u,r),s=l&&u[l],s&&x.acceptData(u)&&s.apply&&s.apply(u,r)===!1&&n.preventDefault();if(n.type=g,!o&&!n.isDefaultPrevented()&&(!p._default||p._default.apply(h.pop(),r)===!1)&&x.acceptData(i)&&l&&i[g]&&!x.isWindow(i)){f=i[l],f&&(i[l]=null),x.event.triggered=g;try{i[g]()}catch(y){}x.event.triggered=t,f&&(i[l]=f)}return n.result}},dispatch:function(e){e=x.event.fix(e);var n,r,i,o,a,s=[],l=g.call(arguments),u=(x._data(this,"events")||{})[e.type]||[],c=x.event.special[e.type]||{};if(l[0]=e,e.delegateTarget=this,!c.preDispatch||c.preDispatch.call(this,e)!==!1){s=x.event.handlers.call(this,e,u),n=0;while((o=s[n++])&&!e.isPropagationStopped()){e.currentTarget=o.elem,a=0;while((i=o.handlers[a++])&&!e.isImmediatePropagationStopped())(!e.namespace_re||e.namespace_re.test(i.namespace))&&(e.handleObj=i,e.data=i.data,r=((x.event.special[i.origType]||{}).handle||i.handler).apply(o.elem,l),r!==t&&(e.result=r)===!1&&(e.preventDefault(),e.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,e),e.result}},handlers:function(e,n){var r,i,o,a,s=[],l=n.delegateCount,u=e.target;if(l&&u.nodeType&&(!e.button||"click"!==e.type))for(;u!=this;u=u.parentNode||this)if(1===u.nodeType&&(u.disabled!==!0||"click"!==e.type)){for(o=[],a=0;l>a;a++)i=n[a],r=i.selector+" ",o[r]===t&&(o[r]=i.needsContext?x(r,this).index(u)>=0:x.find(r,this,null,[u]).length),o[r]&&o.push(i);o.length&&s.push({elem:u,handlers:o})}return n.length>l&&s.push({elem:this,handlers:n.slice(l)}),s},fix:function(e){if(e[x.expando])return e;var t,n,r,i=e.type,o=e,s=this.fixHooks[i];s||(this.fixHooks[i]=s=tt.test(i)?this.mouseHooks:et.test(i)?this.keyHooks:{}),r=s.props?this.props.concat(s.props):this.props,e=new x.Event(o),t=r.length;while(t--)n=r[t],e[n]=o[n];return e.target||(e.target=o.srcElement||a),3===e.target.nodeType&&(e.target=e.target.parentNode),e.metaKey=!!e.metaKey,s.filter?s.filter(e,o):e},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return null==e.which&&(e.which=null!=t.charCode?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,n){var r,i,o,s=n.button,l=n.fromElement;return null==e.pageX&&null!=n.clientX&&(i=e.target.ownerDocument||a,o=i.documentElement,r=i.body,e.pageX=n.clientX+(o&&o.scrollLeft||r&&r.scrollLeft||0)-(o&&o.clientLeft||r&&r.clientLeft||0),e.pageY=n.clientY+(o&&o.scrollTop||r&&r.scrollTop||0)-(o&&o.clientTop||r&&r.clientTop||0)),!e.relatedTarget&&l&&(e.relatedTarget=l===e.target?n.toElement:l),e.which||s===t||(e.which=1&s?1:2&s?3:4&s?2:0),e}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==at()&&this.focus)try{return this.focus(),!1}catch(e){}},delegateType:"focusin"},blur:{trigger:function(){return this===at()&&this.blur?(this.blur(),!1):t},delegateType:"focusout"},click:{trigger:function(){return x.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):t},_default:function(e){return x.nodeName(e.target,"a")}},beforeunload:{postDispatch:function(e){e.result!==t&&(e.originalEvent.returnValue=e.result)}}},simulate:function(e,t,n,r){var i=x.extend(new x.Event,n,{type:e,isSimulated:!0,originalEvent:{}});r?x.event.trigger(i,null,t):x.event.dispatch.call(t,i),i.isDefaultPrevented()&&n.preventDefault()}},x.removeEvent=a.removeEventListener?function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n,!1)}:function(e,t,n){var r="on"+t;e.detachEvent&&(typeof e[r]===i&&(e[r]=null),e.detachEvent(r,n))},x.Event=function(e,n){return this instanceof x.Event?(e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||e.returnValue===!1||e.getPreventDefault&&e.getPreventDefault()?it:ot):this.type=e,n&&x.extend(this,n),this.timeStamp=e&&e.timeStamp||x.now(),this[x.expando]=!0,t):new x.Event(e,n)},x.Event.prototype={isDefaultPrevented:ot,isPropagationStopped:ot,isImmediatePropagationStopped:ot,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=it,e&&(e.preventDefault?e.preventDefault():e.returnValue=!1)},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=it,e&&(e.stopPropagation&&e.stopPropagation(),e.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=it,this.stopPropagation()}},x.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(e,t){x.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj;return(!i||i!==r&&!x.contains(r,i))&&(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),x.support.submitBubbles||(x.event.special.submit={setup:function(){return x.nodeName(this,"form")?!1:(x.event.add(this,"click._submit keypress._submit",function(e){var n=e.target,r=x.nodeName(n,"input")||x.nodeName(n,"button")?n.form:t;r&&!x._data(r,"submitBubbles")&&(x.event.add(r,"submit._submit",function(e){e._submit_bubble=!0}),x._data(r,"submitBubbles",!0))}),t)},postDispatch:function(e){e._submit_bubble&&(delete e._submit_bubble,this.parentNode&&!e.isTrigger&&x.event.simulate("submit",this.parentNode,e,!0))},teardown:function(){return x.nodeName(this,"form")?!1:(x.event.remove(this,"._submit"),t)}}),x.support.changeBubbles||(x.event.special.change={setup:function(){return Z.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(x.event.add(this,"propertychange._change",function(e){"checked"===e.originalEvent.propertyName&&(this._just_changed=!0)}),x.event.add(this,"click._change",function(e){this._just_changed&&!e.isTrigger&&(this._just_changed=!1),x.event.simulate("change",this,e,!0)})),!1):(x.event.add(this,"beforeactivate._change",function(e){var t=e.target;Z.test(t.nodeName)&&!x._data(t,"changeBubbles")&&(x.event.add(t,"change._change",function(e){!this.parentNode||e.isSimulated||e.isTrigger||x.event.simulate("change",this.parentNode,e,!0)}),x._data(t,"changeBubbles",!0))}),t)},handle:function(e){var n=e.target;return this!==n||e.isSimulated||e.isTrigger||"radio"!==n.type&&"checkbox"!==n.type?e.handleObj.handler.apply(this,arguments):t},teardown:function(){return x.event.remove(this,"._change"),!Z.test(this.nodeName)}}),x.support.focusinBubbles||x.each({focus:"focusin",blur:"focusout"},function(e,t){var n=0,r=function(e){x.event.simulate(t,e.target,x.event.fix(e),!0)};x.event.special[t]={setup:function(){0===n++&&a.addEventListener(e,r,!0)},teardown:function(){0===--n&&a.removeEventListener(e,r,!0)}}}),x.fn.extend({on:function(e,n,r,i,o){var a,s;if("object"==typeof e){"string"!=typeof n&&(r=r||n,n=t);for(a in e)this.on(a,n,r,e[a],o);return this}if(null==r&&null==i?(i=n,r=n=t):null==i&&("string"==typeof n?(i=r,r=t):(i=r,r=n,n=t)),i===!1)i=ot;else if(!i)return this;return 1===o&&(s=i,i=function(e){return x().off(e),s.apply(this,arguments)},i.guid=s.guid||(s.guid=x.guid++)),this.each(function(){x.event.add(this,e,i,r,n)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,n,r){var i,o;if(e&&e.preventDefault&&e.handleObj)return i=e.handleObj,x(e.delegateTarget).off(i.namespace?i.origType+"."+i.namespace:i.origType,i.selector,i.handler),this;if("object"==typeof e){for(o in e)this.off(o,n,e[o]);return this}return(n===!1||"function"==typeof n)&&(r=n,n=t),r===!1&&(r=ot),this.each(function(){x.event.remove(this,e,r,n)})},trigger:function(e,t){return this.each(function(){x.event.trigger(e,t,this)})},triggerHandler:function(e,n){var r=this[0];return r?x.event.trigger(e,n,r,!0):t}});var st=/^.[^:#\[\.,]*$/,lt=/^(?:parents|prev(?:Until|All))/,ut=x.expr.match.needsContext,ct={children:!0,contents:!0,next:!0,prev:!0};x.fn.extend({find:function(e){var t,n=[],r=this,i=r.length;if("string"!=typeof e)return this.pushStack(x(e).filter(function(){for(t=0;i>t;t++)if(x.contains(r[t],this))return!0}));for(t=0;i>t;t++)x.find(e,r[t],n);return n=this.pushStack(i>1?x.unique(n):n),n.selector=this.selector?this.selector+" "+e:e,n},has:function(e){var t,n=x(e,this),r=n.length;return this.filter(function(){for(t=0;r>t;t++)if(x.contains(this,n[t]))return!0})},not:function(e){return this.pushStack(ft(this,e||[],!0))},filter:function(e){return this.pushStack(ft(this,e||[],!1))},is:function(e){return!!ft(this,"string"==typeof e&&ut.test(e)?x(e):e||[],!1).length},closest:function(e,t){var n,r=0,i=this.length,o=[],a=ut.test(e)||"string"!=typeof e?x(e,t||this.context):0;for(;i>r;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(11>n.nodeType&&(a?a.index(n)>-1:1===n.nodeType&&x.find.matchesSelector(n,e))){n=o.push(n);break}return this.pushStack(o.length>1?x.unique(o):o)},index:function(e){return e?"string"==typeof e?x.inArray(this[0],x(e)):x.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){var n="string"==typeof e?x(e,t):x.makeArray(e&&e.nodeType?[e]:e),r=x.merge(this.get(),n);return this.pushStack(x.unique(r))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}});function pt(e,t){do e=e[t];while(e&&1!==e.nodeType);return e}x.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return x.dir(e,"parentNode")},parentsUntil:function(e,t,n){return x.dir(e,"parentNode",n)},next:function(e){return pt(e,"nextSibling")},prev:function(e){return pt(e,"previousSibling")},nextAll:function(e){return x.dir(e,"nextSibling")},prevAll:function(e){return x.dir(e,"previousSibling")},nextUntil:function(e,t,n){return x.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return x.dir(e,"previousSibling",n)},siblings:function(e){return x.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return x.sibling(e.firstChild)},contents:function(e){return x.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:x.merge([],e.childNodes)}},function(e,t){x.fn[e]=function(n,r){var i=x.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(i=x.filter(r,i)),this.length>1&&(ct[e]||(i=x.unique(i)),lt.test(e)&&(i=i.reverse())),this.pushStack(i)}}),x.extend({filter:function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?x.find.matchesSelector(r,e)?[r]:[]:x.find.matches(e,x.grep(t,function(e){return 1===e.nodeType}))},dir:function(e,n,r){var i=[],o=e[n];while(o&&9!==o.nodeType&&(r===t||1!==o.nodeType||!x(o).is(r)))1===o.nodeType&&i.push(o),o=o[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}});function ft(e,t,n){if(x.isFunction(t))return x.grep(e,function(e,r){return!!t.call(e,r,e)!==n});if(t.nodeType)return x.grep(e,function(e){return e===t!==n});if("string"==typeof t){if(st.test(t))return x.filter(t,e,n);t=x.filter(t,e)}return x.grep(e,function(e){return x.inArray(e,t)>=0!==n})}function dt(e){var t=ht.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}var ht="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",gt=/ jQuery\d+="(?:null|\d+)"/g,mt=RegExp("<(?:"+ht+")[\\s/>]","i"),yt=/^\s+/,vt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bt=/<([\w:]+)/,xt=/<tbody/i,wt=/<|&#?\w+;/,Tt=/<(?:script|style|link)/i,Ct=/^(?:checkbox|radio)$/i,Nt=/checked\s*(?:[^=]|=\s*.checked.)/i,kt=/^$|\/(?:java|ecma)script/i,Et=/^true\/(.*)/,St=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,At={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:x.support.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]},jt=dt(a),Dt=jt.appendChild(a.createElement("div"));At.optgroup=At.option,At.tbody=At.tfoot=At.colgroup=At.caption=At.thead,At.th=At.td,x.fn.extend({text:function(e){return x.access(this,function(e){return e===t?x.text(this):this.empty().append((this[0]&&this[0].ownerDocument||a).createTextNode(e))},null,e,arguments.length)},append:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Lt(this,e);t.appendChild(e)}})},prepend:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Lt(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},remove:function(e,t){var n,r=e?x.filter(e,this):this,i=0;for(;null!=(n=r[i]);i++)t||1!==n.nodeType||x.cleanData(Ft(n)),n.parentNode&&(t&&x.contains(n.ownerDocument,n)&&_t(Ft(n,"script")),n.parentNode.removeChild(n));return this},empty:function(){var e,t=0;for(;null!=(e=this[t]);t++){1===e.nodeType&&x.cleanData(Ft(e,!1));while(e.firstChild)e.removeChild(e.firstChild);e.options&&x.nodeName(e,"select")&&(e.options.length=0)}return this},clone:function(e,t){return e=null==e?!1:e,t=null==t?e:t,this.map(function(){return x.clone(this,e,t)})},html:function(e){return x.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return 1===n.nodeType?n.innerHTML.replace(gt,""):t;if(!("string"!=typeof e||Tt.test(e)||!x.support.htmlSerialize&&mt.test(e)||!x.support.leadingWhitespace&&yt.test(e)||At[(bt.exec(e)||["",""])[1].toLowerCase()])){e=e.replace(vt,"<$1></$2>");try{for(;i>r;r++)n=this[r]||{},1===n.nodeType&&(x.cleanData(Ft(n,!1)),n.innerHTML=e);n=0}catch(o){}}n&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var e=x.map(this,function(e){return[e.nextSibling,e.parentNode]}),t=0;return this.domManip(arguments,function(n){var r=e[t++],i=e[t++];i&&(r&&r.parentNode!==i&&(r=this.nextSibling),x(this).remove(),i.insertBefore(n,r))},!0),t?this:this.remove()},detach:function(e){return this.remove(e,!0)},domManip:function(e,t,n){e=d.apply([],e);var r,i,o,a,s,l,u=0,c=this.length,p=this,f=c-1,h=e[0],g=x.isFunction(h);if(g||!(1>=c||"string"!=typeof h||x.support.checkClone)&&Nt.test(h))return this.each(function(r){var i=p.eq(r);g&&(e[0]=h.call(this,r,i.html())),i.domManip(e,t,n)});if(c&&(l=x.buildFragment(e,this[0].ownerDocument,!1,!n&&this),r=l.firstChild,1===l.childNodes.length&&(l=r),r)){for(a=x.map(Ft(l,"script"),Ht),o=a.length;c>u;u++)i=l,u!==f&&(i=x.clone(i,!0,!0),o&&x.merge(a,Ft(i,"script"))),t.call(this[u],i,u);if(o)for(s=a[a.length-1].ownerDocument,x.map(a,qt),u=0;o>u;u++)i=a[u],kt.test(i.type||"")&&!x._data(i,"globalEval")&&x.contains(s,i)&&(i.src?x._evalUrl(i.src):x.globalEval((i.text||i.textContent||i.innerHTML||"").replace(St,"")));l=r=null}return this}});function Lt(e,t){return x.nodeName(e,"table")&&x.nodeName(1===t.nodeType?t:t.firstChild,"tr")?e.getElementsByTagName("tbody")[0]||e.appendChild(e.ownerDocument.createElement("tbody")):e}function Ht(e){return e.type=(null!==x.find.attr(e,"type"))+"/"+e.type,e}function qt(e){var t=Et.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function _t(e,t){var n,r=0;for(;null!=(n=e[r]);r++)x._data(n,"globalEval",!t||x._data(t[r],"globalEval"))}function Mt(e,t){if(1===t.nodeType&&x.hasData(e)){var n,r,i,o=x._data(e),a=x._data(t,o),s=o.events;if(s){delete a.handle,a.events={};for(n in s)for(r=0,i=s[n].length;i>r;r++)x.event.add(t,n,s[n][r])}a.data&&(a.data=x.extend({},a.data))}}function Ot(e,t){var n,r,i;if(1===t.nodeType){if(n=t.nodeName.toLowerCase(),!x.support.noCloneEvent&&t[x.expando]){i=x._data(t);for(r in i.events)x.removeEvent(t,r,i.handle);t.removeAttribute(x.expando)}"script"===n&&t.text!==e.text?(Ht(t).text=e.text,qt(t)):"object"===n?(t.parentNode&&(t.outerHTML=e.outerHTML),x.support.html5Clone&&e.innerHTML&&!x.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):"input"===n&&Ct.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):"option"===n?t.defaultSelected=t.selected=e.defaultSelected:("input"===n||"textarea"===n)&&(t.defaultValue=e.defaultValue)}}x.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){x.fn[e]=function(e){var n,r=0,i=[],o=x(e),a=o.length-1;for(;a>=r;r++)n=r===a?this:this.clone(!0),x(o[r])[t](n),h.apply(i,n.get());return this.pushStack(i)}});function Ft(e,n){var r,o,a=0,s=typeof e.getElementsByTagName!==i?e.getElementsByTagName(n||"*"):typeof e.querySelectorAll!==i?e.querySelectorAll(n||"*"):t;if(!s)for(s=[],r=e.childNodes||e;null!=(o=r[a]);a++)!n||x.nodeName(o,n)?s.push(o):x.merge(s,Ft(o,n));return n===t||n&&x.nodeName(e,n)?x.merge([e],s):s}function Bt(e){Ct.test(e.type)&&(e.defaultChecked=e.checked)}x.extend({clone:function(e,t,n){var r,i,o,a,s,l=x.contains(e.ownerDocument,e);if(x.support.html5Clone||x.isXMLDoc(e)||!mt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(Dt.innerHTML=e.outerHTML,Dt.removeChild(o=Dt.firstChild)),!(x.support.noCloneEvent&&x.support.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||x.isXMLDoc(e)))for(r=Ft(o),s=Ft(e),a=0;null!=(i=s[a]);++a)r[a]&&Ot(i,r[a]);if(t)if(n)for(s=s||Ft(e),r=r||Ft(o),a=0;null!=(i=s[a]);a++)Mt(i,r[a]);else Mt(e,o);return r=Ft(o,"script"),r.length>0&&_t(r,!l&&Ft(e,"script")),r=s=i=null,o},buildFragment:function(e,t,n,r){var i,o,a,s,l,u,c,p=e.length,f=dt(t),d=[],h=0;for(;p>h;h++)if(o=e[h],o||0===o)if("object"===x.type(o))x.merge(d,o.nodeType?[o]:o);else if(wt.test(o)){s=s||f.appendChild(t.createElement("div")),l=(bt.exec(o)||["",""])[1].toLowerCase(),c=At[l]||At._default,s.innerHTML=c[1]+o.replace(vt,"<$1></$2>")+c[2],i=c[0];while(i--)s=s.lastChild;if(!x.support.leadingWhitespace&&yt.test(o)&&d.push(t.createTextNode(yt.exec(o)[0])),!x.support.tbody){o="table"!==l||xt.test(o)?"<table>"!==c[1]||xt.test(o)?0:s:s.firstChild,i=o&&o.childNodes.length;while(i--)x.nodeName(u=o.childNodes[i],"tbody")&&!u.childNodes.length&&o.removeChild(u)}x.merge(d,s.childNodes),s.textContent="";while(s.firstChild)s.removeChild(s.firstChild);s=f.lastChild}else d.push(t.createTextNode(o));s&&f.removeChild(s),x.support.appendChecked||x.grep(Ft(d,"input"),Bt),h=0;while(o=d[h++])if((!r||-1===x.inArray(o,r))&&(a=x.contains(o.ownerDocument,o),s=Ft(f.appendChild(o),"script"),a&&_t(s),n)){i=0;while(o=s[i++])kt.test(o.type||"")&&n.push(o)}return s=null,f},cleanData:function(e,t){var n,r,o,a,s=0,l=x.expando,u=x.cache,c=x.support.deleteExpando,f=x.event.special;for(;null!=(n=e[s]);s++)if((t||x.acceptData(n))&&(o=n[l],a=o&&u[o])){if(a.events)for(r in a.events)f[r]?x.event.remove(n,r):x.removeEvent(n,r,a.handle);u[o]&&(delete u[o],c?delete n[l]:typeof n.removeAttribute!==i?n.removeAttribute(l):n[l]=null,p.push(o))}},_evalUrl:function(e){return x.ajax({url:e,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})
12 }}),x.fn.extend({wrapAll:function(e){if(x.isFunction(e))return this.each(function(t){x(this).wrapAll(e.call(this,t))});if(this[0]){var t=x(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&1===e.firstChild.nodeType)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return x.isFunction(e)?this.each(function(t){x(this).wrapInner(e.call(this,t))}):this.each(function(){var t=x(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=x.isFunction(e);return this.each(function(n){x(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){x.nodeName(this,"body")||x(this).replaceWith(this.childNodes)}).end()}});var Pt,Rt,Wt,$t=/alpha\([^)]*\)/i,It=/opacity\s*=\s*([^)]*)/,zt=/^(top|right|bottom|left)$/,Xt=/^(none|table(?!-c[ea]).+)/,Ut=/^margin/,Vt=RegExp("^("+w+")(.*)$","i"),Yt=RegExp("^("+w+")(?!px)[a-z%]+$","i"),Jt=RegExp("^([+-])=("+w+")","i"),Gt={BODY:"block"},Qt={position:"absolute",visibility:"hidden",display:"block"},Kt={letterSpacing:0,fontWeight:400},Zt=["Top","Right","Bottom","Left"],en=["Webkit","O","Moz","ms"];function tn(e,t){if(t in e)return t;var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=en.length;while(i--)if(t=en[i]+n,t in e)return t;return r}function nn(e,t){return e=t||e,"none"===x.css(e,"display")||!x.contains(e.ownerDocument,e)}function rn(e,t){var n,r,i,o=[],a=0,s=e.length;for(;s>a;a++)r=e[a],r.style&&(o[a]=x._data(r,"olddisplay"),n=r.style.display,t?(o[a]||"none"!==n||(r.style.display=""),""===r.style.display&&nn(r)&&(o[a]=x._data(r,"olddisplay",ln(r.nodeName)))):o[a]||(i=nn(r),(n&&"none"!==n||!i)&&x._data(r,"olddisplay",i?n:x.css(r,"display"))));for(a=0;s>a;a++)r=e[a],r.style&&(t&&"none"!==r.style.display&&""!==r.style.display||(r.style.display=t?o[a]||"":"none"));return e}x.fn.extend({css:function(e,n){return x.access(this,function(e,n,r){var i,o,a={},s=0;if(x.isArray(n)){for(o=Rt(e),i=n.length;i>s;s++)a[n[s]]=x.css(e,n[s],!1,o);return a}return r!==t?x.style(e,n,r):x.css(e,n)},e,n,arguments.length>1)},show:function(){return rn(this,!0)},hide:function(){return rn(this)},toggle:function(e){var t="boolean"==typeof e;return this.each(function(){(t?e:nn(this))?x(this).show():x(this).hide()})}}),x.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Wt(e,"opacity");return""===n?"1":n}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":x.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var o,a,s,l=x.camelCase(n),u=e.style;if(n=x.cssProps[l]||(x.cssProps[l]=tn(u,l)),s=x.cssHooks[n]||x.cssHooks[l],r===t)return s&&"get"in s&&(o=s.get(e,!1,i))!==t?o:u[n];if(a=typeof r,"string"===a&&(o=Jt.exec(r))&&(r=(o[1]+1)*o[2]+parseFloat(x.css(e,n)),a="number"),!(null==r||"number"===a&&isNaN(r)||("number"!==a||x.cssNumber[l]||(r+="px"),x.support.clearCloneStyle||""!==r||0!==n.indexOf("background")||(u[n]="inherit"),s&&"set"in s&&(r=s.set(e,r,i))===t)))try{u[n]=r}catch(c){}}},css:function(e,n,r,i){var o,a,s,l=x.camelCase(n);return n=x.cssProps[l]||(x.cssProps[l]=tn(e.style,l)),s=x.cssHooks[n]||x.cssHooks[l],s&&"get"in s&&(a=s.get(e,!0,r)),a===t&&(a=Wt(e,n,i)),"normal"===a&&n in Kt&&(a=Kt[n]),""===r||r?(o=parseFloat(a),r===!0||x.isNumeric(o)?o||0:a):a}}),e.getComputedStyle?(Rt=function(t){return e.getComputedStyle(t,null)},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),l=s?s.getPropertyValue(n)||s[n]:t,u=e.style;return s&&(""!==l||x.contains(e.ownerDocument,e)||(l=x.style(e,n)),Yt.test(l)&&Ut.test(n)&&(i=u.width,o=u.minWidth,a=u.maxWidth,u.minWidth=u.maxWidth=u.width=l,l=s.width,u.width=i,u.minWidth=o,u.maxWidth=a)),l}):a.documentElement.currentStyle&&(Rt=function(e){return e.currentStyle},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),l=s?s[n]:t,u=e.style;return null==l&&u&&u[n]&&(l=u[n]),Yt.test(l)&&!zt.test(n)&&(i=u.left,o=e.runtimeStyle,a=o&&o.left,a&&(o.left=e.currentStyle.left),u.left="fontSize"===n?"1em":l,l=u.pixelLeft+"px",u.left=i,a&&(o.left=a)),""===l?"auto":l});function on(e,t,n){var r=Vt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function an(e,t,n,r,i){var o=n===(r?"border":"content")?4:"width"===t?1:0,a=0;for(;4>o;o+=2)"margin"===n&&(a+=x.css(e,n+Zt[o],!0,i)),r?("content"===n&&(a-=x.css(e,"padding"+Zt[o],!0,i)),"margin"!==n&&(a-=x.css(e,"border"+Zt[o]+"Width",!0,i))):(a+=x.css(e,"padding"+Zt[o],!0,i),"padding"!==n&&(a+=x.css(e,"border"+Zt[o]+"Width",!0,i)));return a}function sn(e,t,n){var r=!0,i="width"===t?e.offsetWidth:e.offsetHeight,o=Rt(e),a=x.support.boxSizing&&"border-box"===x.css(e,"boxSizing",!1,o);if(0>=i||null==i){if(i=Wt(e,t,o),(0>i||null==i)&&(i=e.style[t]),Yt.test(i))return i;r=a&&(x.support.boxSizingReliable||i===e.style[t]),i=parseFloat(i)||0}return i+an(e,t,n||(a?"border":"content"),r,o)+"px"}function ln(e){var t=a,n=Gt[e];return n||(n=un(e,t),"none"!==n&&n||(Pt=(Pt||x("<iframe frameborder='0' width='0' height='0'/>").css("cssText","display:block !important")).appendTo(t.documentElement),t=(Pt[0].contentWindow||Pt[0].contentDocument).document,t.write("<!doctype html><html><body>"),t.close(),n=un(e,t),Pt.detach()),Gt[e]=n),n}function un(e,t){var n=x(t.createElement(e)).appendTo(t.body),r=x.css(n[0],"display");return n.remove(),r}x.each(["height","width"],function(e,n){x.cssHooks[n]={get:function(e,r,i){return r?0===e.offsetWidth&&Xt.test(x.css(e,"display"))?x.swap(e,Qt,function(){return sn(e,n,i)}):sn(e,n,i):t},set:function(e,t,r){var i=r&&Rt(e);return on(e,t,r?an(e,n,r,x.support.boxSizing&&"border-box"===x.css(e,"boxSizing",!1,i),i):0)}}}),x.support.opacity||(x.cssHooks.opacity={get:function(e,t){return It.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":t?"1":""},set:function(e,t){var n=e.style,r=e.currentStyle,i=x.isNumeric(t)?"alpha(opacity="+100*t+")":"",o=r&&r.filter||n.filter||"";n.zoom=1,(t>=1||""===t)&&""===x.trim(o.replace($t,""))&&n.removeAttribute&&(n.removeAttribute("filter"),""===t||r&&!r.filter)||(n.filter=$t.test(o)?o.replace($t,i):o+" "+i)}}),x(function(){x.support.reliableMarginRight||(x.cssHooks.marginRight={get:function(e,n){return n?x.swap(e,{display:"inline-block"},Wt,[e,"marginRight"]):t}}),!x.support.pixelPosition&&x.fn.position&&x.each(["top","left"],function(e,n){x.cssHooks[n]={get:function(e,r){return r?(r=Wt(e,n),Yt.test(r)?x(e).position()[n]+"px":r):t}}})}),x.expr&&x.expr.filters&&(x.expr.filters.hidden=function(e){return 0>=e.offsetWidth&&0>=e.offsetHeight||!x.support.reliableHiddenOffsets&&"none"===(e.style&&e.style.display||x.css(e,"display"))},x.expr.filters.visible=function(e){return!x.expr.filters.hidden(e)}),x.each({margin:"",padding:"",border:"Width"},function(e,t){x.cssHooks[e+t]={expand:function(n){var r=0,i={},o="string"==typeof n?n.split(" "):[n];for(;4>r;r++)i[e+Zt[r]+t]=o[r]||o[r-2]||o[0];return i}},Ut.test(e)||(x.cssHooks[e+t].set=on)});var cn=/%20/g,pn=/\[\]$/,fn=/\r?\n/g,dn=/^(?:submit|button|image|reset|file)$/i,hn=/^(?:input|select|textarea|keygen)/i;x.fn.extend({serialize:function(){return x.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=x.prop(this,"elements");return e?x.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!x(this).is(":disabled")&&hn.test(this.nodeName)&&!dn.test(e)&&(this.checked||!Ct.test(e))}).map(function(e,t){var n=x(this).val();return null==n?null:x.isArray(n)?x.map(n,function(e){return{name:t.name,value:e.replace(fn,"\r\n")}}):{name:t.name,value:n.replace(fn,"\r\n")}}).get()}}),x.param=function(e,n){var r,i=[],o=function(e,t){t=x.isFunction(t)?t():null==t?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};if(n===t&&(n=x.ajaxSettings&&x.ajaxSettings.traditional),x.isArray(e)||e.jquery&&!x.isPlainObject(e))x.each(e,function(){o(this.name,this.value)});else for(r in e)gn(r,e[r],n,o);return i.join("&").replace(cn,"+")};function gn(e,t,n,r){var i;if(x.isArray(t))x.each(t,function(t,i){n||pn.test(e)?r(e,i):gn(e+"["+("object"==typeof i?t:"")+"]",i,n,r)});else if(n||"object"!==x.type(t))r(e,t);else for(i in t)gn(e+"["+i+"]",t[i],n,r)}x.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(e,t){x.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),x.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)},bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)}});var mn,yn,vn=x.now(),bn=/\?/,xn=/#.*$/,wn=/([?&])_=[^&]*/,Tn=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Cn=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Nn=/^(?:GET|HEAD)$/,kn=/^\/\//,En=/^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,Sn=x.fn.load,An={},jn={},Dn="*/".concat("*");try{yn=o.href}catch(Ln){yn=a.createElement("a"),yn.href="",yn=yn.href}mn=En.exec(yn.toLowerCase())||[];function Hn(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(T)||[];if(x.isFunction(n))while(r=o[i++])"+"===r[0]?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function qn(e,n,r,i){var o={},a=e===jn;function s(l){var u;return o[l]=!0,x.each(e[l]||[],function(e,l){var c=l(n,r,i);return"string"!=typeof c||a||o[c]?a?!(u=c):t:(n.dataTypes.unshift(c),s(c),!1)}),u}return s(n.dataTypes[0])||!o["*"]&&s("*")}function _n(e,n){var r,i,o=x.ajaxSettings.flatOptions||{};for(i in n)n[i]!==t&&((o[i]?e:r||(r={}))[i]=n[i]);return r&&x.extend(!0,e,r),e}x.fn.load=function(e,n,r){if("string"!=typeof e&&Sn)return Sn.apply(this,arguments);var i,o,a,s=this,l=e.indexOf(" ");return l>=0&&(i=e.slice(l,e.length),e=e.slice(0,l)),x.isFunction(n)?(r=n,n=t):n&&"object"==typeof n&&(a="POST"),s.length>0&&x.ajax({url:e,type:a,dataType:"html",data:n}).done(function(e){o=arguments,s.html(i?x("<div>").append(x.parseHTML(e)).find(i):e)}).complete(r&&function(e,t){s.each(r,o||[e.responseText,t,e])}),this},x.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){x.fn[t]=function(e){return this.on(t,e)}}),x.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:yn,type:"GET",isLocal:Cn.test(mn[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Dn,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":x.parseJSON,"text xml":x.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?_n(_n(e,x.ajaxSettings),t):_n(x.ajaxSettings,e)},ajaxPrefilter:Hn(An),ajaxTransport:Hn(jn),ajax:function(e,n){"object"==typeof e&&(n=e,e=t),n=n||{};var r,i,o,a,s,l,u,c,p=x.ajaxSetup({},n),f=p.context||p,d=p.context&&(f.nodeType||f.jquery)?x(f):x.event,h=x.Deferred(),g=x.Callbacks("once memory"),m=p.statusCode||{},y={},v={},b=0,w="canceled",C={readyState:0,getResponseHeader:function(e){var t;if(2===b){if(!c){c={};while(t=Tn.exec(a))c[t[1].toLowerCase()]=t[2]}t=c[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return 2===b?a:null},setRequestHeader:function(e,t){var n=e.toLowerCase();return b||(e=v[n]=v[n]||e,y[e]=t),this},overrideMimeType:function(e){return b||(p.mimeType=e),this},statusCode:function(e){var t;if(e)if(2>b)for(t in e)m[t]=[m[t],e[t]];else C.always(e[C.status]);return this},abort:function(e){var t=e||w;return u&&u.abort(t),k(0,t),this}};if(h.promise(C).complete=g.add,C.success=C.done,C.error=C.fail,p.url=((e||p.url||yn)+"").replace(xn,"").replace(kn,mn[1]+"//"),p.type=n.method||n.type||p.method||p.type,p.dataTypes=x.trim(p.dataType||"*").toLowerCase().match(T)||[""],null==p.crossDomain&&(r=En.exec(p.url.toLowerCase()),p.crossDomain=!(!r||r[1]===mn[1]&&r[2]===mn[2]&&(r[3]||("http:"===r[1]?"80":"443"))===(mn[3]||("http:"===mn[1]?"80":"443")))),p.data&&p.processData&&"string"!=typeof p.data&&(p.data=x.param(p.data,p.traditional)),qn(An,p,n,C),2===b)return C;l=p.global,l&&0===x.active++&&x.event.trigger("ajaxStart"),p.type=p.type.toUpperCase(),p.hasContent=!Nn.test(p.type),o=p.url,p.hasContent||(p.data&&(o=p.url+=(bn.test(o)?"&":"?")+p.data,delete p.data),p.cache===!1&&(p.url=wn.test(o)?o.replace(wn,"$1_="+vn++):o+(bn.test(o)?"&":"?")+"_="+vn++)),p.ifModified&&(x.lastModified[o]&&C.setRequestHeader("If-Modified-Since",x.lastModified[o]),x.etag[o]&&C.setRequestHeader("If-None-Match",x.etag[o])),(p.data&&p.hasContent&&p.contentType!==!1||n.contentType)&&C.setRequestHeader("Content-Type",p.contentType),C.setRequestHeader("Accept",p.dataTypes[0]&&p.accepts[p.dataTypes[0]]?p.accepts[p.dataTypes[0]]+("*"!==p.dataTypes[0]?", "+Dn+"; q=0.01":""):p.accepts["*"]);for(i in p.headers)C.setRequestHeader(i,p.headers[i]);if(p.beforeSend&&(p.beforeSend.call(f,C,p)===!1||2===b))return C.abort();w="abort";for(i in{success:1,error:1,complete:1})C[i](p[i]);if(u=qn(jn,p,n,C)){C.readyState=1,l&&d.trigger("ajaxSend",[C,p]),p.async&&p.timeout>0&&(s=setTimeout(function(){C.abort("timeout")},p.timeout));try{b=1,u.send(y,k)}catch(N){if(!(2>b))throw N;k(-1,N)}}else k(-1,"No Transport");function k(e,n,r,i){var c,y,v,w,T,N=n;2!==b&&(b=2,s&&clearTimeout(s),u=t,a=i||"",C.readyState=e>0?4:0,c=e>=200&&300>e||304===e,r&&(w=Mn(p,C,r)),w=On(p,w,C,c),c?(p.ifModified&&(T=C.getResponseHeader("Last-Modified"),T&&(x.lastModified[o]=T),T=C.getResponseHeader("etag"),T&&(x.etag[o]=T)),204===e||"HEAD"===p.type?N="nocontent":304===e?N="notmodified":(N=w.state,y=w.data,v=w.error,c=!v)):(v=N,(e||!N)&&(N="error",0>e&&(e=0))),C.status=e,C.statusText=(n||N)+"",c?h.resolveWith(f,[y,N,C]):h.rejectWith(f,[C,N,v]),C.statusCode(m),m=t,l&&d.trigger(c?"ajaxSuccess":"ajaxError",[C,p,c?y:v]),g.fireWith(f,[C,N]),l&&(d.trigger("ajaxComplete",[C,p]),--x.active||x.event.trigger("ajaxStop")))}return C},getJSON:function(e,t,n){return x.get(e,t,n,"json")},getScript:function(e,n){return x.get(e,t,n,"script")}}),x.each(["get","post"],function(e,n){x[n]=function(e,r,i,o){return x.isFunction(r)&&(o=o||i,i=r,r=t),x.ajax({url:e,type:n,dataType:o,data:r,success:i})}});function Mn(e,n,r){var i,o,a,s,l=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),o===t&&(o=e.mimeType||n.getResponseHeader("Content-Type"));if(o)for(s in l)if(l[s]&&l[s].test(o)){u.unshift(s);break}if(u[0]in r)a=u[0];else{for(s in r){if(!u[0]||e.converters[s+" "+u[0]]){a=s;break}i||(i=s)}a=a||i}return a?(a!==u[0]&&u.unshift(a),r[a]):t}function On(e,t,n,r){var i,o,a,s,l,u={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)u[a.toLowerCase()]=e.converters[a];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!l&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),l=o,o=c.shift())if("*"===o)o=l;else if("*"!==l&&l!==o){if(a=u[l+" "+o]||u["* "+o],!a)for(i in u)if(s=i.split(" "),s[1]===o&&(a=u[l+" "+s[0]]||u["* "+s[0]])){a===!0?a=u[i]:u[i]!==!0&&(o=s[0],c.unshift(s[1]));break}if(a!==!0)if(a&&e["throws"])t=a(t);else try{t=a(t)}catch(p){return{state:"parsererror",error:a?p:"No conversion from "+l+" to "+o}}}return{state:"success",data:t}}x.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(e){return x.globalEval(e),e}}}),x.ajaxPrefilter("script",function(e){e.cache===t&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),x.ajaxTransport("script",function(e){if(e.crossDomain){var n,r=a.head||x("head")[0]||a.documentElement;return{send:function(t,i){n=a.createElement("script"),n.async=!0,e.scriptCharset&&(n.charset=e.scriptCharset),n.src=e.url,n.onload=n.onreadystatechange=function(e,t){(t||!n.readyState||/loaded|complete/.test(n.readyState))&&(n.onload=n.onreadystatechange=null,n.parentNode&&n.parentNode.removeChild(n),n=null,t||i(200,"success"))},r.insertBefore(n,r.firstChild)},abort:function(){n&&n.onload(t,!0)}}}});var Fn=[],Bn=/(=)\?(?=&|$)|\?\?/;x.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Fn.pop()||x.expando+"_"+vn++;return this[e]=!0,e}}),x.ajaxPrefilter("json jsonp",function(n,r,i){var o,a,s,l=n.jsonp!==!1&&(Bn.test(n.url)?"url":"string"==typeof n.data&&!(n.contentType||"").indexOf("application/x-www-form-urlencoded")&&Bn.test(n.data)&&"data");return l||"jsonp"===n.dataTypes[0]?(o=n.jsonpCallback=x.isFunction(n.jsonpCallback)?n.jsonpCallback():n.jsonpCallback,l?n[l]=n[l].replace(Bn,"$1"+o):n.jsonp!==!1&&(n.url+=(bn.test(n.url)?"&":"?")+n.jsonp+"="+o),n.converters["script json"]=function(){return s||x.error(o+" was not called"),s[0]},n.dataTypes[0]="json",a=e[o],e[o]=function(){s=arguments},i.always(function(){e[o]=a,n[o]&&(n.jsonpCallback=r.jsonpCallback,Fn.push(o)),s&&x.isFunction(a)&&a(s[0]),s=a=t}),"script"):t});var Pn,Rn,Wn=0,$n=e.ActiveXObject&&function(){var e;for(e in Pn)Pn[e](t,!0)};function In(){try{return new e.XMLHttpRequest}catch(t){}}function zn(){try{return new e.ActiveXObject("Microsoft.XMLHTTP")}catch(t){}}x.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&In()||zn()}:In,Rn=x.ajaxSettings.xhr(),x.support.cors=!!Rn&&"withCredentials"in Rn,Rn=x.support.ajax=!!Rn,Rn&&x.ajaxTransport(function(n){if(!n.crossDomain||x.support.cors){var r;return{send:function(i,o){var a,s,l=n.xhr();if(n.username?l.open(n.type,n.url,n.async,n.username,n.password):l.open(n.type,n.url,n.async),n.xhrFields)for(s in n.xhrFields)l[s]=n.xhrFields[s];n.mimeType&&l.overrideMimeType&&l.overrideMimeType(n.mimeType),n.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest");try{for(s in i)l.setRequestHeader(s,i[s])}catch(u){}l.send(n.hasContent&&n.data||null),r=function(e,i){var s,u,c,p;try{if(r&&(i||4===l.readyState))if(r=t,a&&(l.onreadystatechange=x.noop,$n&&delete Pn[a]),i)4!==l.readyState&&l.abort();else{p={},s=l.status,u=l.getAllResponseHeaders(),"string"==typeof l.responseText&&(p.text=l.responseText);try{c=l.statusText}catch(f){c=""}s||!n.isLocal||n.crossDomain?1223===s&&(s=204):s=p.text?200:404}}catch(d){i||o(-1,d)}p&&o(s,c,p,u)},n.async?4===l.readyState?setTimeout(r):(a=++Wn,$n&&(Pn||(Pn={},x(e).unload($n)),Pn[a]=r),l.onreadystatechange=r):r()},abort:function(){r&&r(t,!0)}}}});var Xn,Un,Vn=/^(?:toggle|show|hide)$/,Yn=RegExp("^(?:([+-])=|)("+w+")([a-z%]*)$","i"),Jn=/queueHooks$/,Gn=[nr],Qn={"*":[function(e,t){var n=this.createTween(e,t),r=n.cur(),i=Yn.exec(t),o=i&&i[3]||(x.cssNumber[e]?"":"px"),a=(x.cssNumber[e]||"px"!==o&&+r)&&Yn.exec(x.css(n.elem,e)),s=1,l=20;if(a&&a[3]!==o){o=o||a[3],i=i||[],a=+r||1;do s=s||".5",a/=s,x.style(n.elem,e,a+o);while(s!==(s=n.cur()/r)&&1!==s&&--l)}return i&&(n.unit=o,n.start=+a||+r||0,n.end=i[1]?a+(i[1]+1)*i[2]:+i[2]),n}]};function Kn(){return setTimeout(function(){Xn=t}),Xn=x.now()}function Zn(e,t,n){var r,i=(Qn[t]||[]).concat(Qn["*"]),o=0,a=i.length;for(;a>o;o++)if(r=i[o].call(n,t,e))return r}function er(e,t,n){var r,i,o=0,a=Gn.length,s=x.Deferred().always(function(){delete l.elem}),l=function(){if(i)return!1;var t=Xn||Kn(),n=Math.max(0,u.startTime+u.duration-t),r=n/u.duration||0,o=1-r,a=0,l=u.tweens.length;for(;l>a;a++)u.tweens[a].run(o);return s.notifyWith(e,[u,o,n]),1>o&&l?n:(s.resolveWith(e,[u]),!1)},u=s.promise({elem:e,props:x.extend({},t),opts:x.extend(!0,{specialEasing:{}},n),originalProperties:t,originalOptions:n,startTime:Xn||Kn(),duration:n.duration,tweens:[],createTween:function(t,n){var r=x.Tween(e,u.opts,t,n,u.opts.specialEasing[t]||u.opts.easing);return u.tweens.push(r),r},stop:function(t){var n=0,r=t?u.tweens.length:0;if(i)return this;for(i=!0;r>n;n++)u.tweens[n].run(1);return t?s.resolveWith(e,[u,t]):s.rejectWith(e,[u,t]),this}}),c=u.props;for(tr(c,u.opts.specialEasing);a>o;o++)if(r=Gn[o].call(u,e,c,u.opts))return r;return x.map(c,Zn,u),x.isFunction(u.opts.start)&&u.opts.start.call(e,u),x.fx.timer(x.extend(l,{elem:e,anim:u,queue:u.opts.queue})),u.progress(u.opts.progress).done(u.opts.done,u.opts.complete).fail(u.opts.fail).always(u.opts.always)}function tr(e,t){var n,r,i,o,a;for(n in e)if(r=x.camelCase(n),i=t[r],o=e[n],x.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),a=x.cssHooks[r],a&&"expand"in a){o=a.expand(o),delete e[r];for(n in o)n in e||(e[n]=o[n],t[n]=i)}else t[r]=i}x.Animation=x.extend(er,{tweener:function(e,t){x.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;i>r;r++)n=e[r],Qn[n]=Qn[n]||[],Qn[n].unshift(t)},prefilter:function(e,t){t?Gn.unshift(e):Gn.push(e)}});function nr(e,t,n){var r,i,o,a,s,l,u=this,c={},p=e.style,f=e.nodeType&&nn(e),d=x._data(e,"fxshow");n.queue||(s=x._queueHooks(e,"fx"),null==s.unqueued&&(s.unqueued=0,l=s.empty.fire,s.empty.fire=function(){s.unqueued||l()}),s.unqueued++,u.always(function(){u.always(function(){s.unqueued--,x.queue(e,"fx").length||s.empty.fire()})})),1===e.nodeType&&("height"in t||"width"in t)&&(n.overflow=[p.overflow,p.overflowX,p.overflowY],"inline"===x.css(e,"display")&&"none"===x.css(e,"float")&&(x.support.inlineBlockNeedsLayout&&"inline"!==ln(e.nodeName)?p.zoom=1:p.display="inline-block")),n.overflow&&(p.overflow="hidden",x.support.shrinkWrapBlocks||u.always(function(){p.overflow=n.overflow[0],p.overflowX=n.overflow[1],p.overflowY=n.overflow[2]}));for(r in t)if(i=t[r],Vn.exec(i)){if(delete t[r],o=o||"toggle"===i,i===(f?"hide":"show"))continue;c[r]=d&&d[r]||x.style(e,r)}if(!x.isEmptyObject(c)){d?"hidden"in d&&(f=d.hidden):d=x._data(e,"fxshow",{}),o&&(d.hidden=!f),f?x(e).show():u.done(function(){x(e).hide()}),u.done(function(){var t;x._removeData(e,"fxshow");for(t in c)x.style(e,t,c[t])});for(r in c)a=Zn(f?d[r]:0,r,u),r in d||(d[r]=a.start,f&&(a.end=a.start,a.start="width"===r||"height"===r?1:0))}}function rr(e,t,n,r,i){return new rr.prototype.init(e,t,n,r,i)}x.Tween=rr,rr.prototype={constructor:rr,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||"swing",this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(x.cssNumber[n]?"":"px")},cur:function(){var e=rr.propHooks[this.prop];return e&&e.get?e.get(this):rr.propHooks._default.get(this)},run:function(e){var t,n=rr.propHooks[this.prop];return this.pos=t=this.options.duration?x.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):rr.propHooks._default.set(this),this}},rr.prototype.init.prototype=rr.prototype,rr.propHooks={_default:{get:function(e){var t;return null==e.elem[e.prop]||e.elem.style&&null!=e.elem.style[e.prop]?(t=x.css(e.elem,e.prop,""),t&&"auto"!==t?t:0):e.elem[e.prop]},set:function(e){x.fx.step[e.prop]?x.fx.step[e.prop](e):e.elem.style&&(null!=e.elem.style[x.cssProps[e.prop]]||x.cssHooks[e.prop])?x.style(e.elem,e.prop,e.now+e.unit):e.elem[e.prop]=e.now}}},rr.propHooks.scrollTop=rr.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},x.each(["toggle","show","hide"],function(e,t){var n=x.fn[t];x.fn[t]=function(e,r,i){return null==e||"boolean"==typeof e?n.apply(this,arguments):this.animate(ir(t,!0),e,r,i)}}),x.fn.extend({fadeTo:function(e,t,n,r){return this.filter(nn).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=x.isEmptyObject(e),o=x.speed(t,n,r),a=function(){var t=er(this,x.extend({},e),o);a.finish=function(){t.stop(!0)},(i||x._data(this,"finish"))&&t.stop(!0)};return a.finish=a,i||o.queue===!1?this.each(a):this.queue(o.queue,a)},stop:function(e,n,r){var i=function(e){var t=e.stop;delete e.stop,t(r)};return"string"!=typeof e&&(r=n,n=e,e=t),n&&e!==!1&&this.queue(e||"fx",[]),this.each(function(){var t=!0,n=null!=e&&e+"queueHooks",o=x.timers,a=x._data(this);if(n)a[n]&&a[n].stop&&i(a[n]);else for(n in a)a[n]&&a[n].stop&&Jn.test(n)&&i(a[n]);for(n=o.length;n--;)o[n].elem!==this||null!=e&&o[n].queue!==e||(o[n].anim.stop(r),t=!1,o.splice(n,1));(t||!r)&&x.dequeue(this,e)})},finish:function(e){return e!==!1&&(e=e||"fx"),this.each(function(){var t,n=x._data(this),r=n[e+"queue"],i=n[e+"queueHooks"],o=x.timers,a=r?r.length:0;for(n.finish=!0,x.queue(this,e,[]),i&&i.cur&&i.cur.finish&&i.cur.finish.call(this),t=o.length;t--;)o[t].elem===this&&o[t].queue===e&&(o[t].anim.stop(!0),o.splice(t,1));for(t=0;a>t;t++)r[t]&&r[t].finish&&r[t].finish.call(this);delete n.finish})}});function ir(e,t){var n,r={height:e},i=0;for(t=t?1:0;4>i;i+=2-t)n=Zt[i],r["margin"+n]=r["padding"+n]=e;return t&&(r.opacity=r.width=e),r}x.each({slideDown:ir("show"),slideUp:ir("hide"),slideToggle:ir("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){x.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),x.speed=function(e,t,n){var r=e&&"object"==typeof e?x.extend({},e):{complete:n||!n&&t||x.isFunction(e)&&e,duration:e,easing:n&&t||t&&!x.isFunction(t)&&t};return r.duration=x.fx.off?0:"number"==typeof r.duration?r.duration:r.duration in x.fx.speeds?x.fx.speeds[r.duration]:x.fx.speeds._default,(null==r.queue||r.queue===!0)&&(r.queue="fx"),r.old=r.complete,r.complete=function(){x.isFunction(r.old)&&r.old.call(this),r.queue&&x.dequeue(this,r.queue)},r},x.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2}},x.timers=[],x.fx=rr.prototype.init,x.fx.tick=function(){var e,n=x.timers,r=0;for(Xn=x.now();n.length>r;r++)e=n[r],e()||n[r]!==e||n.splice(r--,1);n.length||x.fx.stop(),Xn=t},x.fx.timer=function(e){e()&&x.timers.push(e)&&x.fx.start()},x.fx.interval=13,x.fx.start=function(){Un||(Un=setInterval(x.fx.tick,x.fx.interval))},x.fx.stop=function(){clearInterval(Un),Un=null},x.fx.speeds={slow:600,fast:200,_default:400},x.fx.step={},x.expr&&x.expr.filters&&(x.expr.filters.animated=function(e){return x.grep(x.timers,function(t){return e===t.elem}).length}),x.fn.offset=function(e){if(arguments.length)return e===t?this:this.each(function(t){x.offset.setOffset(this,e,t)});var n,r,o={top:0,left:0},a=this[0],s=a&&a.ownerDocument;if(s)return n=s.documentElement,x.contains(n,a)?(typeof a.getBoundingClientRect!==i&&(o=a.getBoundingClientRect()),r=or(s),{top:o.top+(r.pageYOffset||n.scrollTop)-(n.clientTop||0),left:o.left+(r.pageXOffset||n.scrollLeft)-(n.clientLeft||0)}):o},x.offset={setOffset:function(e,t,n){var r=x.css(e,"position");"static"===r&&(e.style.position="relative");var i=x(e),o=i.offset(),a=x.css(e,"top"),s=x.css(e,"left"),l=("absolute"===r||"fixed"===r)&&x.inArray("auto",[a,s])>-1,u={},c={},p,f;l?(c=i.position(),p=c.top,f=c.left):(p=parseFloat(a)||0,f=parseFloat(s)||0),x.isFunction(t)&&(t=t.call(e,n,o)),null!=t.top&&(u.top=t.top-o.top+p),null!=t.left&&(u.left=t.left-o.left+f),"using"in t?t.using.call(e,u):i.css(u)}},x.fn.extend({position:function(){if(this[0]){var e,t,n={top:0,left:0},r=this[0];return"fixed"===x.css(r,"position")?t=r.getBoundingClientRect():(e=this.offsetParent(),t=this.offset(),x.nodeName(e[0],"html")||(n=e.offset()),n.top+=x.css(e[0],"borderTopWidth",!0),n.left+=x.css(e[0],"borderLeftWidth",!0)),{top:t.top-n.top-x.css(r,"marginTop",!0),left:t.left-n.left-x.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||s;while(e&&!x.nodeName(e,"html")&&"static"===x.css(e,"position"))e=e.offsetParent;return e||s})}}),x.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,n){var r=/Y/.test(n);x.fn[e]=function(i){return x.access(this,function(e,i,o){var a=or(e);return o===t?a?n in a?a[n]:a.document.documentElement[i]:e[i]:(a?a.scrollTo(r?x(a).scrollLeft():o,r?o:x(a).scrollTop()):e[i]=o,t)},e,i,arguments.length,null)}});function or(e){return x.isWindow(e)?e:9===e.nodeType?e.defaultView||e.parentWindow:!1}x.each({Height:"height",Width:"width"},function(e,n){x.each({padding:"inner"+e,content:n,"":"outer"+e},function(r,i){x.fn[i]=function(i,o){var a=arguments.length&&(r||"boolean"!=typeof i),s=r||(i===!0||o===!0?"margin":"border");return x.access(this,function(n,r,i){var o;return x.isWindow(n)?n.document.documentElement["client"+e]:9===n.nodeType?(o=n.documentElement,Math.max(n.body["scroll"+e],o["scroll"+e],n.body["offset"+e],o["offset"+e],o["client"+e])):i===t?x.css(n,r,s):x.style(n,r,i,s)},n,a?i:t,a,null)}})}),x.fn.size=function(){return this.length},x.fn.andSelf=x.fn.addBack,"object"==typeof module&&"object"==typeof module.exports?module.exports=x:(e.jQuery=e.$=x,"function"==typeof define&&define.amd&&define("jquery",[],function(){return x}))})(window);
13 /**
14  * jQuery JSON plugin 2.4.0
15  *
16  * @author Brantley Harris, 2009-2011
17  * @author Timo Tijhof, 2011-2012
18  * @source This plugin is heavily influenced by MochiKit's serializeJSON, which is
19  *         copyrighted 2005 by Bob Ippolito.
20  * @source Brantley Harris wrote this plugin. It is based somewhat on the JSON.org
21  *         website's http://www.json.org/json2.js, which proclaims:
22  *         "NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.", a sentiment that
23  *         I uphold.
24  * @license MIT License <http://www.opensource.org/licenses/mit-license.php>
25  */
26 (function ($) {
27         'use strict';
28
29         var escape = /["\\\x00-\x1f\x7f-\x9f]/g,
30                 meta = {
31                         '\b': '\\b',
32                         '\t': '\\t',
33                         '\n': '\\n',
34                         '\f': '\\f',
35                         '\r': '\\r',
36                         '"' : '\\"',
37                         '\\': '\\\\'
38                 },
39                 hasOwn = Object.prototype.hasOwnProperty;
40
41         /**
42          * jQuery.toJSON
43          * Converts the given argument into a JSON representation.
44          *
45          * @param o {Mixed} The json-serializable *thing* to be converted
46          *
47          * If an object has a toJSON prototype, that will be used to get the representation.
48          * Non-integer/string keys are skipped in the object, as are keys that point to a
49          * function.
50          *
51          */
52         $.toJSON = typeof JSON === 'object' && JSON.stringify ? JSON.stringify : function (o) {
53                 if (o === null) {
54                         return 'null';
55                 }
56
57                 var pairs, k, name, val,
58                         type = $.type(o);
59
60                 if (type === 'undefined') {
61                         return undefined;
62                 }
63
64                 // Also covers instantiated Number and Boolean objects,
65                 // which are typeof 'object' but thanks to $.type, we
66                 // catch them here. I don't know whether it is right
67                 // or wrong that instantiated primitives are not
68                 // exported to JSON as an {"object":..}.
69                 // We choose this path because that's what the browsers did.
70                 if (type === 'number' || type === 'boolean') {
71                         return String(o);
72                 }
73                 if (type === 'string') {
74                         return $.quoteString(o);
75                 }
76                 if (typeof o.toJSON === 'function') {
77                         return $.toJSON(o.toJSON());
78                 }
79                 if (type === 'date') {
80                         var month = o.getUTCMonth() + 1,
81                                 day = o.getUTCDate(),
82                                 year = o.getUTCFullYear(),
83                                 hours = o.getUTCHours(),
84                                 minutes = o.getUTCMinutes(),
85                                 seconds = o.getUTCSeconds(),
86                                 milli = o.getUTCMilliseconds();
87
88                         if (month < 10) {
89                                 month = '0' + month;
90                         }
91                         if (day < 10) {
92                                 day = '0' + day;
93                         }
94                         if (hours < 10) {
95                                 hours = '0' + hours;
96                         }
97                         if (minutes < 10) {
98                                 minutes = '0' + minutes;
99                         }
100                         if (seconds < 10) {
101                                 seconds = '0' + seconds;
102                         }
103                         if (milli < 100) {
104                                 milli = '0' + milli;
105                         }
106                         if (milli < 10) {
107                                 milli = '0' + milli;
108                         }
109                         return '"' + year + '-' + month + '-' + day + 'T' +
110                                 hours + ':' + minutes + ':' + seconds +
111                                 '.' + milli + 'Z"';
112                 }
113
114                 pairs = [];
115
116                 if ($.isArray(o)) {
117                         for (k = 0; k < o.length; k++) {
118                                 pairs.push($.toJSON(o[k]) || 'null');
119                         }
120                         return '[' + pairs.join(',') + ']';
121                 }
122
123                 // Any other object (plain object, RegExp, ..)
124                 // Need to do typeof instead of $.type, because we also
125                 // want to catch non-plain objects.
126                 if (typeof o === 'object') {
127                         for (k in o) {
128                                 // Only include own properties,
129                                 // Filter out inherited prototypes
130                                 if (hasOwn.call(o, k)) {
131                                         // Keys must be numerical or string. Skip others
132                                         type = typeof k;
133                                         if (type === 'number') {
134                                                 name = '"' + k + '"';
135                                         } else if (type === 'string') {
136                                                 name = $.quoteString(k);
137                                         } else {
138                                                 continue;
139                                         }
140                                         type = typeof o[k];
141
142                                         // Invalid values like these return undefined
143                                         // from toJSON, however those object members
144                                         // shouldn't be included in the JSON string at all.
145                                         if (type !== 'function' && type !== 'undefined') {
146                                                 val = $.toJSON(o[k]);
147                                                 pairs.push(name + ':' + val);
148                                         }
149                                 }
150                         }
151                         return '{' + pairs.join(',') + '}';
152                 }
153         };
154
155         /**
156          * jQuery.evalJSON
157          * Evaluates a given json string.
158          *
159          * @param str {String}
160          */
161         $.evalJSON = typeof JSON === 'object' && JSON.parse ? JSON.parse : function (str) {
162                 /*jshint evil: true */
163                 return eval('(' + str + ')');
164         };
165
166         /**
167          * jQuery.secureEvalJSON
168          * Evals JSON in a way that is *more* secure.
169          *
170          * @param str {String}
171          */
172         $.secureEvalJSON = typeof JSON === 'object' && JSON.parse ? JSON.parse : function (str) {
173                 var filtered =
174                         str
175                         .replace(/\\["\\\/bfnrtu]/g, '@')
176                         .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
177                         .replace(/(?:^|:|,)(?:\s*\[)+/g, '');
178
179                 if (/^[\],:{}\s]*$/.test(filtered)) {
180                         /*jshint evil: true */
181                         return eval('(' + str + ')');
182                 }
183                 throw new SyntaxError('Error parsing JSON, source is not valid.');
184         };
185
186         /**
187          * jQuery.quoteString
188          * Returns a string-repr of a string, escaping quotes intelligently.
189          * Mostly a support function for toJSON.
190          * Examples:
191          * >>> jQuery.quoteString('apple')
192          * "apple"
193          *
194          * >>> jQuery.quoteString('"Where are we going?", she asked.')
195          * "\"Where are we going?\", she asked."
196          */
197         $.quoteString = function (str) {
198                 if (str.match(escape)) {
199                         return '"' + str.replace(escape, function (a) {
200                                 var c = meta[a];
201                                 if (typeof c === 'string') {
202                                         return c;
203                                 }
204                                 c = a.charCodeAt();
205                                 return '\\u00' + Math.floor(c / 16).toString(16) + (c % 16).toString(16);
206                         }) + '"';
207                 }
208                 return '"' + str + '"';
209         };
210
211 }(jQuery));
212 mkws_jQuery = jQuery.noConflict(true);
213 /*!
214
215  handlebars v2.0.0
216
217 Copyright (C) 2011-2014 by Yehuda Katz
218
219 Permission is hereby granted, free of charge, to any person obtaining a copy
220 of this software and associated documentation files (the "Software"), to deal
221 in the Software without restriction, including without limitation the rights
222 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
223 copies of the Software, and to permit persons to whom the Software is
224 furnished to do so, subject to the following conditions:
225
226 The above copyright notice and this permission notice shall be included in
227 all copies or substantial portions of the Software.
228
229 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
230 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
231 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
232 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
233 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
234 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
235 THE SOFTWARE.
236
237 @license
238 */
239 /* exported Handlebars */
240 (function (root, factory) {
241   if (typeof define === 'function' && define.amd) {
242     define([], factory);
243   } else if (typeof exports === 'object') {
244     module.exports = factory();
245   } else {
246     root.Handlebars = root.Handlebars || factory();
247   }
248 }(this, function () {
249 // handlebars/safe-string.js
250 var __module4__ = (function() {
251   "use strict";
252   var __exports__;
253   // Build out our basic SafeString type
254   function SafeString(string) {
255     this.string = string;
256   }
257
258   SafeString.prototype.toString = function() {
259     return "" + this.string;
260   };
261
262   __exports__ = SafeString;
263   return __exports__;
264 })();
265
266 // handlebars/utils.js
267 var __module3__ = (function(__dependency1__) {
268   "use strict";
269   var __exports__ = {};
270   /*jshint -W004 */
271   var SafeString = __dependency1__;
272
273   var escape = {
274     "&": "&amp;",
275     "<": "&lt;",
276     ">": "&gt;",
277     '"': "&quot;",
278     "'": "&#x27;",
279     "`": "&#x60;"
280   };
281
282   var badChars = /[&<>"'`]/g;
283   var possible = /[&<>"'`]/;
284
285   function escapeChar(chr) {
286     return escape[chr];
287   }
288
289   function extend(obj /* , ...source */) {
290     for (var i = 1; i < arguments.length; i++) {
291       for (var key in arguments[i]) {
292         if (Object.prototype.hasOwnProperty.call(arguments[i], key)) {
293           obj[key] = arguments[i][key];
294         }
295       }
296     }
297
298     return obj;
299   }
300
301   __exports__.extend = extend;var toString = Object.prototype.toString;
302   __exports__.toString = toString;
303   // Sourced from lodash
304   // https://github.com/bestiejs/lodash/blob/master/LICENSE.txt
305   var isFunction = function(value) {
306     return typeof value === 'function';
307   };
308   // fallback for older versions of Chrome and Safari
309   /* istanbul ignore next */
310   if (isFunction(/x/)) {
311     isFunction = function(value) {
312       return typeof value === 'function' && toString.call(value) === '[object Function]';
313     };
314   }
315   var isFunction;
316   __exports__.isFunction = isFunction;
317   /* istanbul ignore next */
318   var isArray = Array.isArray || function(value) {
319     return (value && typeof value === 'object') ? toString.call(value) === '[object Array]' : false;
320   };
321   __exports__.isArray = isArray;
322
323   function escapeExpression(string) {
324     // don't escape SafeStrings, since they're already safe
325     if (string instanceof SafeString) {
326       return string.toString();
327     } else if (string == null) {
328       return "";
329     } else if (!string) {
330       return string + '';
331     }
332
333     // Force a string conversion as this will be done by the append regardless and
334     // the regex test will do this transparently behind the scenes, causing issues if
335     // an object's to string has escaped characters in it.
336     string = "" + string;
337
338     if(!possible.test(string)) { return string; }
339     return string.replace(badChars, escapeChar);
340   }
341
342   __exports__.escapeExpression = escapeExpression;function isEmpty(value) {
343     if (!value && value !== 0) {
344       return true;
345     } else if (isArray(value) && value.length === 0) {
346       return true;
347     } else {
348       return false;
349     }
350   }
351
352   __exports__.isEmpty = isEmpty;function appendContextPath(contextPath, id) {
353     return (contextPath ? contextPath + '.' : '') + id;
354   }
355
356   __exports__.appendContextPath = appendContextPath;
357   return __exports__;
358 })(__module4__);
359
360 // handlebars/exception.js
361 var __module5__ = (function() {
362   "use strict";
363   var __exports__;
364
365   var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];
366
367   function Exception(message, node) {
368     var line;
369     if (node && node.firstLine) {
370       line = node.firstLine;
371
372       message += ' - ' + line + ':' + node.firstColumn;
373     }
374
375     var tmp = Error.prototype.constructor.call(this, message);
376
377     // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
378     for (var idx = 0; idx < errorProps.length; idx++) {
379       this[errorProps[idx]] = tmp[errorProps[idx]];
380     }
381
382     if (line) {
383       this.lineNumber = line;
384       this.column = node.firstColumn;
385     }
386   }
387
388   Exception.prototype = new Error();
389
390   __exports__ = Exception;
391   return __exports__;
392 })();
393
394 // handlebars/base.js
395 var __module2__ = (function(__dependency1__, __dependency2__) {
396   "use strict";
397   var __exports__ = {};
398   var Utils = __dependency1__;
399   var Exception = __dependency2__;
400
401   var VERSION = "2.0.0";
402   __exports__.VERSION = VERSION;var COMPILER_REVISION = 6;
403   __exports__.COMPILER_REVISION = COMPILER_REVISION;
404   var REVISION_CHANGES = {
405     1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it
406     2: '== 1.0.0-rc.3',
407     3: '== 1.0.0-rc.4',
408     4: '== 1.x.x',
409     5: '== 2.0.0-alpha.x',
410     6: '>= 2.0.0-beta.1'
411   };
412   __exports__.REVISION_CHANGES = REVISION_CHANGES;
413   var isArray = Utils.isArray,
414       isFunction = Utils.isFunction,
415       toString = Utils.toString,
416       objectType = '[object Object]';
417
418   function HandlebarsEnvironment(helpers, partials) {
419     this.helpers = helpers || {};
420     this.partials = partials || {};
421
422     registerDefaultHelpers(this);
423   }
424
425   __exports__.HandlebarsEnvironment = HandlebarsEnvironment;HandlebarsEnvironment.prototype = {
426     constructor: HandlebarsEnvironment,
427
428     logger: logger,
429     log: log,
430
431     registerHelper: function(name, fn) {
432       if (toString.call(name) === objectType) {
433         if (fn) { throw new Exception('Arg not supported with multiple helpers'); }
434         Utils.extend(this.helpers, name);
435       } else {
436         this.helpers[name] = fn;
437       }
438     },
439     unregisterHelper: function(name) {
440       delete this.helpers[name];
441     },
442
443     registerPartial: function(name, partial) {
444       if (toString.call(name) === objectType) {
445         Utils.extend(this.partials,  name);
446       } else {
447         this.partials[name] = partial;
448       }
449     },
450     unregisterPartial: function(name) {
451       delete this.partials[name];
452     }
453   };
454
455   function registerDefaultHelpers(instance) {
456     instance.registerHelper('helperMissing', function(/* [args, ]options */) {
457       if(arguments.length === 1) {
458         // A missing field in a {{foo}} constuct.
459         return undefined;
460       } else {
461         // Someone is actually trying to call something, blow up.
462         throw new Exception("Missing helper: '" + arguments[arguments.length-1].name + "'");
463       }
464     });
465
466     instance.registerHelper('blockHelperMissing', function(context, options) {
467       var inverse = options.inverse,
468           fn = options.fn;
469
470       if(context === true) {
471         return fn(this);
472       } else if(context === false || context == null) {
473         return inverse(this);
474       } else if (isArray(context)) {
475         if(context.length > 0) {
476           if (options.ids) {
477             options.ids = [options.name];
478           }
479
480           return instance.helpers.each(context, options);
481         } else {
482           return inverse(this);
483         }
484       } else {
485         if (options.data && options.ids) {
486           var data = createFrame(options.data);
487           data.contextPath = Utils.appendContextPath(options.data.contextPath, options.name);
488           options = {data: data};
489         }
490
491         return fn(context, options);
492       }
493     });
494
495     instance.registerHelper('each', function(context, options) {
496       if (!options) {
497         throw new Exception('Must pass iterator to #each');
498       }
499
500       var fn = options.fn, inverse = options.inverse;
501       var i = 0, ret = "", data;
502
503       var contextPath;
504       if (options.data && options.ids) {
505         contextPath = Utils.appendContextPath(options.data.contextPath, options.ids[0]) + '.';
506       }
507
508       if (isFunction(context)) { context = context.call(this); }
509
510       if (options.data) {
511         data = createFrame(options.data);
512       }
513
514       if(context && typeof context === 'object') {
515         if (isArray(context)) {
516           for(var j = context.length; i<j; i++) {
517             if (data) {
518               data.index = i;
519               data.first = (i === 0);
520               data.last  = (i === (context.length-1));
521
522               if (contextPath) {
523                 data.contextPath = contextPath + i;
524               }
525             }
526             ret = ret + fn(context[i], { data: data });
527           }
528         } else {
529           for(var key in context) {
530             if(context.hasOwnProperty(key)) {
531               if(data) {
532                 data.key = key;
533                 data.index = i;
534                 data.first = (i === 0);
535
536                 if (contextPath) {
537                   data.contextPath = contextPath + key;
538                 }
539               }
540               ret = ret + fn(context[key], {data: data});
541               i++;
542             }
543           }
544         }
545       }
546
547       if(i === 0){
548         ret = inverse(this);
549       }
550
551       return ret;
552     });
553
554     instance.registerHelper('if', function(conditional, options) {
555       if (isFunction(conditional)) { conditional = conditional.call(this); }
556
557       // Default behavior is to render the positive path if the value is truthy and not empty.
558       // The `includeZero` option may be set to treat the condtional as purely not empty based on the
559       // behavior of isEmpty. Effectively this determines if 0 is handled by the positive path or negative.
560       if ((!options.hash.includeZero && !conditional) || Utils.isEmpty(conditional)) {
561         return options.inverse(this);
562       } else {
563         return options.fn(this);
564       }
565     });
566
567     instance.registerHelper('unless', function(conditional, options) {
568       return instance.helpers['if'].call(this, conditional, {fn: options.inverse, inverse: options.fn, hash: options.hash});
569     });
570
571     instance.registerHelper('with', function(context, options) {
572       if (isFunction(context)) { context = context.call(this); }
573
574       var fn = options.fn;
575
576       if (!Utils.isEmpty(context)) {
577         if (options.data && options.ids) {
578           var data = createFrame(options.data);
579           data.contextPath = Utils.appendContextPath(options.data.contextPath, options.ids[0]);
580           options = {data:data};
581         }
582
583         return fn(context, options);
584       } else {
585         return options.inverse(this);
586       }
587     });
588
589     instance.registerHelper('log', function(message, options) {
590       var level = options.data && options.data.level != null ? parseInt(options.data.level, 10) : 1;
591       instance.log(level, message);
592     });
593
594     instance.registerHelper('lookup', function(obj, field) {
595       return obj && obj[field];
596     });
597   }
598
599   var logger = {
600     methodMap: { 0: 'debug', 1: 'info', 2: 'warn', 3: 'error' },
601
602     // State enum
603     DEBUG: 0,
604     INFO: 1,
605     WARN: 2,
606     ERROR: 3,
607     level: 3,
608
609     // can be overridden in the host environment
610     log: function(level, message) {
611       if (logger.level <= level) {
612         var method = logger.methodMap[level];
613         if (typeof console !== 'undefined' && console[method]) {
614           console[method].call(console, message);
615         }
616       }
617     }
618   };
619   __exports__.logger = logger;
620   var log = logger.log;
621   __exports__.log = log;
622   var createFrame = function(object) {
623     var frame = Utils.extend({}, object);
624     frame._parent = object;
625     return frame;
626   };
627   __exports__.createFrame = createFrame;
628   return __exports__;
629 })(__module3__, __module5__);
630
631 // handlebars/runtime.js
632 var __module6__ = (function(__dependency1__, __dependency2__, __dependency3__) {
633   "use strict";
634   var __exports__ = {};
635   var Utils = __dependency1__;
636   var Exception = __dependency2__;
637   var COMPILER_REVISION = __dependency3__.COMPILER_REVISION;
638   var REVISION_CHANGES = __dependency3__.REVISION_CHANGES;
639   var createFrame = __dependency3__.createFrame;
640
641   function checkRevision(compilerInfo) {
642     var compilerRevision = compilerInfo && compilerInfo[0] || 1,
643         currentRevision = COMPILER_REVISION;
644
645     if (compilerRevision !== currentRevision) {
646       if (compilerRevision < currentRevision) {
647         var runtimeVersions = REVISION_CHANGES[currentRevision],
648             compilerVersions = REVISION_CHANGES[compilerRevision];
649         throw new Exception("Template was precompiled with an older version of Handlebars than the current runtime. "+
650               "Please update your precompiler to a newer version ("+runtimeVersions+") or downgrade your runtime to an older version ("+compilerVersions+").");
651       } else {
652         // Use the embedded version info since the runtime doesn't know about this revision yet
653         throw new Exception("Template was precompiled with a newer version of Handlebars than the current runtime. "+
654               "Please update your runtime to a newer version ("+compilerInfo[1]+").");
655       }
656     }
657   }
658
659   __exports__.checkRevision = checkRevision;// TODO: Remove this line and break up compilePartial
660
661   function template(templateSpec, env) {
662     /* istanbul ignore next */
663     if (!env) {
664       throw new Exception("No environment passed to template");
665     }
666     if (!templateSpec || !templateSpec.main) {
667       throw new Exception('Unknown template object: ' + typeof templateSpec);
668     }
669
670     // Note: Using env.VM references rather than local var references throughout this section to allow
671     // for external users to override these as psuedo-supported APIs.
672     env.VM.checkRevision(templateSpec.compiler);
673
674     var invokePartialWrapper = function(partial, indent, name, context, hash, helpers, partials, data, depths) {
675       if (hash) {
676         context = Utils.extend({}, context, hash);
677       }
678
679       var result = env.VM.invokePartial.call(this, partial, name, context, helpers, partials, data, depths);
680
681       if (result == null && env.compile) {
682         var options = { helpers: helpers, partials: partials, data: data, depths: depths };
683         partials[name] = env.compile(partial, { data: data !== undefined, compat: templateSpec.compat }, env);
684         result = partials[name](context, options);
685       }
686       if (result != null) {
687         if (indent) {
688           var lines = result.split('\n');
689           for (var i = 0, l = lines.length; i < l; i++) {
690             if (!lines[i] && i + 1 === l) {
691               break;
692             }
693
694             lines[i] = indent + lines[i];
695           }
696           result = lines.join('\n');
697         }
698         return result;
699       } else {
700         throw new Exception("The partial " + name + " could not be compiled when running in runtime-only mode");
701       }
702     };
703
704     // Just add water
705     var container = {
706       lookup: function(depths, name) {
707         var len = depths.length;
708         for (var i = 0; i < len; i++) {
709           if (depths[i] && depths[i][name] != null) {
710             return depths[i][name];
711           }
712         }
713       },
714       lambda: function(current, context) {
715         return typeof current === 'function' ? current.call(context) : current;
716       },
717
718       escapeExpression: Utils.escapeExpression,
719       invokePartial: invokePartialWrapper,
720
721       fn: function(i) {
722         return templateSpec[i];
723       },
724
725       programs: [],
726       program: function(i, data, depths) {
727         var programWrapper = this.programs[i],
728             fn = this.fn(i);
729         if (data || depths) {
730           programWrapper = program(this, i, fn, data, depths);
731         } else if (!programWrapper) {
732           programWrapper = this.programs[i] = program(this, i, fn);
733         }
734         return programWrapper;
735       },
736
737       data: function(data, depth) {
738         while (data && depth--) {
739           data = data._parent;
740         }
741         return data;
742       },
743       merge: function(param, common) {
744         var ret = param || common;
745
746         if (param && common && (param !== common)) {
747           ret = Utils.extend({}, common, param);
748         }
749
750         return ret;
751       },
752
753       noop: env.VM.noop,
754       compilerInfo: templateSpec.compiler
755     };
756
757     var ret = function(context, options) {
758       options = options || {};
759       var data = options.data;
760
761       ret._setup(options);
762       if (!options.partial && templateSpec.useData) {
763         data = initData(context, data);
764       }
765       var depths;
766       if (templateSpec.useDepths) {
767         depths = options.depths ? [context].concat(options.depths) : [context];
768       }
769
770       return templateSpec.main.call(container, context, container.helpers, container.partials, data, depths);
771     };
772     ret.isTop = true;
773
774     ret._setup = function(options) {
775       if (!options.partial) {
776         container.helpers = container.merge(options.helpers, env.helpers);
777
778         if (templateSpec.usePartial) {
779           container.partials = container.merge(options.partials, env.partials);
780         }
781       } else {
782         container.helpers = options.helpers;
783         container.partials = options.partials;
784       }
785     };
786
787     ret._child = function(i, data, depths) {
788       if (templateSpec.useDepths && !depths) {
789         throw new Exception('must pass parent depths');
790       }
791
792       return program(container, i, templateSpec[i], data, depths);
793     };
794     return ret;
795   }
796
797   __exports__.template = template;function program(container, i, fn, data, depths) {
798     var prog = function(context, options) {
799       options = options || {};
800
801       return fn.call(container, context, container.helpers, container.partials, options.data || data, depths && [context].concat(depths));
802     };
803     prog.program = i;
804     prog.depth = depths ? depths.length : 0;
805     return prog;
806   }
807
808   __exports__.program = program;function invokePartial(partial, name, context, helpers, partials, data, depths) {
809     var options = { partial: true, helpers: helpers, partials: partials, data: data, depths: depths };
810
811     if(partial === undefined) {
812       throw new Exception("The partial " + name + " could not be found");
813     } else if(partial instanceof Function) {
814       return partial(context, options);
815     }
816   }
817
818   __exports__.invokePartial = invokePartial;function noop() { return ""; }
819
820   __exports__.noop = noop;function initData(context, data) {
821     if (!data || !('root' in data)) {
822       data = data ? createFrame(data) : {};
823       data.root = context;
824     }
825     return data;
826   }
827   return __exports__;
828 })(__module3__, __module5__, __module2__);
829
830 // handlebars.runtime.js
831 var __module1__ = (function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__) {
832   "use strict";
833   var __exports__;
834   /*globals Handlebars: true */
835   var base = __dependency1__;
836
837   // Each of these augment the Handlebars object. No need to setup here.
838   // (This is done to easily share code between commonjs and browse envs)
839   var SafeString = __dependency2__;
840   var Exception = __dependency3__;
841   var Utils = __dependency4__;
842   var runtime = __dependency5__;
843
844   // For compatibility and usage outside of module systems, make the Handlebars object a namespace
845   var create = function() {
846     var hb = new base.HandlebarsEnvironment();
847
848     Utils.extend(hb, base);
849     hb.SafeString = SafeString;
850     hb.Exception = Exception;
851     hb.Utils = Utils;
852     hb.escapeExpression = Utils.escapeExpression;
853
854     hb.VM = runtime;
855     hb.template = function(spec) {
856       return runtime.template(spec, hb);
857     };
858
859     return hb;
860   };
861
862   var Handlebars = create();
863   Handlebars.create = create;
864
865   Handlebars['default'] = Handlebars;
866
867   __exports__ = Handlebars;
868   return __exports__;
869 })(__module2__, __module4__, __module5__, __module3__, __module6__);
870
871 // handlebars/compiler/ast.js
872 var __module7__ = (function(__dependency1__) {
873   "use strict";
874   var __exports__;
875   var Exception = __dependency1__;
876
877   function LocationInfo(locInfo) {
878     locInfo = locInfo || {};
879     this.firstLine   = locInfo.first_line;
880     this.firstColumn = locInfo.first_column;
881     this.lastColumn  = locInfo.last_column;
882     this.lastLine    = locInfo.last_line;
883   }
884
885   var AST = {
886     ProgramNode: function(statements, strip, locInfo) {
887       LocationInfo.call(this, locInfo);
888       this.type = "program";
889       this.statements = statements;
890       this.strip = strip;
891     },
892
893     MustacheNode: function(rawParams, hash, open, strip, locInfo) {
894       LocationInfo.call(this, locInfo);
895       this.type = "mustache";
896       this.strip = strip;
897
898       // Open may be a string parsed from the parser or a passed boolean flag
899       if (open != null && open.charAt) {
900         // Must use charAt to support IE pre-10
901         var escapeFlag = open.charAt(3) || open.charAt(2);
902         this.escaped = escapeFlag !== '{' && escapeFlag !== '&';
903       } else {
904         this.escaped = !!open;
905       }
906
907       if (rawParams instanceof AST.SexprNode) {
908         this.sexpr = rawParams;
909       } else {
910         // Support old AST API
911         this.sexpr = new AST.SexprNode(rawParams, hash);
912       }
913
914       // Support old AST API that stored this info in MustacheNode
915       this.id = this.sexpr.id;
916       this.params = this.sexpr.params;
917       this.hash = this.sexpr.hash;
918       this.eligibleHelper = this.sexpr.eligibleHelper;
919       this.isHelper = this.sexpr.isHelper;
920     },
921
922     SexprNode: function(rawParams, hash, locInfo) {
923       LocationInfo.call(this, locInfo);
924
925       this.type = "sexpr";
926       this.hash = hash;
927
928       var id = this.id = rawParams[0];
929       var params = this.params = rawParams.slice(1);
930
931       // a mustache is definitely a helper if:
932       // * it is an eligible helper, and
933       // * it has at least one parameter or hash segment
934       this.isHelper = !!(params.length || hash);
935
936       // a mustache is an eligible helper if:
937       // * its id is simple (a single part, not `this` or `..`)
938       this.eligibleHelper = this.isHelper || id.isSimple;
939
940       // if a mustache is an eligible helper but not a definite
941       // helper, it is ambiguous, and will be resolved in a later
942       // pass or at runtime.
943     },
944
945     PartialNode: function(partialName, context, hash, strip, locInfo) {
946       LocationInfo.call(this, locInfo);
947       this.type         = "partial";
948       this.partialName  = partialName;
949       this.context      = context;
950       this.hash = hash;
951       this.strip = strip;
952
953       this.strip.inlineStandalone = true;
954     },
955
956     BlockNode: function(mustache, program, inverse, strip, locInfo) {
957       LocationInfo.call(this, locInfo);
958
959       this.type = 'block';
960       this.mustache = mustache;
961       this.program  = program;
962       this.inverse  = inverse;
963       this.strip = strip;
964
965       if (inverse && !program) {
966         this.isInverse = true;
967       }
968     },
969
970     RawBlockNode: function(mustache, content, close, locInfo) {
971       LocationInfo.call(this, locInfo);
972
973       if (mustache.sexpr.id.original !== close) {
974         throw new Exception(mustache.sexpr.id.original + " doesn't match " + close, this);
975       }
976
977       content = new AST.ContentNode(content, locInfo);
978
979       this.type = 'block';
980       this.mustache = mustache;
981       this.program = new AST.ProgramNode([content], {}, locInfo);
982     },
983
984     ContentNode: function(string, locInfo) {
985       LocationInfo.call(this, locInfo);
986       this.type = "content";
987       this.original = this.string = string;
988     },
989
990     HashNode: function(pairs, locInfo) {
991       LocationInfo.call(this, locInfo);
992       this.type = "hash";
993       this.pairs = pairs;
994     },
995
996     IdNode: function(parts, locInfo) {
997       LocationInfo.call(this, locInfo);
998       this.type = "ID";
999
1000       var original = "",
1001           dig = [],
1002           depth = 0,
1003           depthString = '';
1004
1005       for(var i=0,l=parts.length; i<l; i++) {
1006         var part = parts[i].part;
1007         original += (parts[i].separator || '') + part;
1008
1009         if (part === ".." || part === "." || part === "this") {
1010           if (dig.length > 0) {
1011             throw new Exception("Invalid path: " + original, this);
1012           } else if (part === "..") {
1013             depth++;
1014             depthString += '../';
1015           } else {
1016             this.isScoped = true;
1017           }
1018         } else {
1019           dig.push(part);
1020         }
1021       }
1022
1023       this.original = original;
1024       this.parts    = dig;
1025       this.string   = dig.join('.');
1026       this.depth    = depth;
1027       this.idName   = depthString + this.string;
1028
1029       // an ID is simple if it only has one part, and that part is not
1030       // `..` or `this`.
1031       this.isSimple = parts.length === 1 && !this.isScoped && depth === 0;
1032
1033       this.stringModeValue = this.string;
1034     },
1035
1036     PartialNameNode: function(name, locInfo) {
1037       LocationInfo.call(this, locInfo);
1038       this.type = "PARTIAL_NAME";
1039       this.name = name.original;
1040     },
1041
1042     DataNode: function(id, locInfo) {
1043       LocationInfo.call(this, locInfo);
1044       this.type = "DATA";
1045       this.id = id;
1046       this.stringModeValue = id.stringModeValue;
1047       this.idName = '@' + id.stringModeValue;
1048     },
1049
1050     StringNode: function(string, locInfo) {
1051       LocationInfo.call(this, locInfo);
1052       this.type = "STRING";
1053       this.original =
1054         this.string =
1055         this.stringModeValue = string;
1056     },
1057
1058     NumberNode: function(number, locInfo) {
1059       LocationInfo.call(this, locInfo);
1060       this.type = "NUMBER";
1061       this.original =
1062         this.number = number;
1063       this.stringModeValue = Number(number);
1064     },
1065
1066     BooleanNode: function(bool, locInfo) {
1067       LocationInfo.call(this, locInfo);
1068       this.type = "BOOLEAN";
1069       this.bool = bool;
1070       this.stringModeValue = bool === "true";
1071     },
1072
1073     CommentNode: function(comment, locInfo) {
1074       LocationInfo.call(this, locInfo);
1075       this.type = "comment";
1076       this.comment = comment;
1077
1078       this.strip = {
1079         inlineStandalone: true
1080       };
1081     }
1082   };
1083
1084
1085   // Must be exported as an object rather than the root of the module as the jison lexer
1086   // most modify the object to operate properly.
1087   __exports__ = AST;
1088   return __exports__;
1089 })(__module5__);
1090
1091 // handlebars/compiler/parser.js
1092 var __module9__ = (function() {
1093   "use strict";
1094   var __exports__;
1095   /* jshint ignore:start */
1096   /* istanbul ignore next */
1097   /* Jison generated parser */
1098   var handlebars = (function(){
1099   var parser = {trace: function trace() { },
1100   yy: {},
1101   symbols_: {"error":2,"root":3,"program":4,"EOF":5,"program_repetition0":6,"statement":7,"mustache":8,"block":9,"rawBlock":10,"partial":11,"CONTENT":12,"COMMENT":13,"openRawBlock":14,"END_RAW_BLOCK":15,"OPEN_RAW_BLOCK":16,"sexpr":17,"CLOSE_RAW_BLOCK":18,"openBlock":19,"block_option0":20,"closeBlock":21,"openInverse":22,"block_option1":23,"OPEN_BLOCK":24,"CLOSE":25,"OPEN_INVERSE":26,"inverseAndProgram":27,"INVERSE":28,"OPEN_ENDBLOCK":29,"path":30,"OPEN":31,"OPEN_UNESCAPED":32,"CLOSE_UNESCAPED":33,"OPEN_PARTIAL":34,"partialName":35,"param":36,"partial_option0":37,"partial_option1":38,"sexpr_repetition0":39,"sexpr_option0":40,"dataName":41,"STRING":42,"NUMBER":43,"BOOLEAN":44,"OPEN_SEXPR":45,"CLOSE_SEXPR":46,"hash":47,"hash_repetition_plus0":48,"hashSegment":49,"ID":50,"EQUALS":51,"DATA":52,"pathSegments":53,"SEP":54,"$accept":0,"$end":1},
1102   terminals_: {2:"error",5:"EOF",12:"CONTENT",13:"COMMENT",15:"END_RAW_BLOCK",16:"OPEN_RAW_BLOCK",18:"CLOSE_RAW_BLOCK",24:"OPEN_BLOCK",25:"CLOSE",26:"OPEN_INVERSE",28:"INVERSE",29:"OPEN_ENDBLOCK",31:"OPEN",32:"OPEN_UNESCAPED",33:"CLOSE_UNESCAPED",34:"OPEN_PARTIAL",42:"STRING",43:"NUMBER",44:"BOOLEAN",45:"OPEN_SEXPR",46:"CLOSE_SEXPR",50:"ID",51:"EQUALS",52:"DATA",54:"SEP"},
1103   productions_: [0,[3,2],[4,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[10,3],[14,3],[9,4],[9,4],[19,3],[22,3],[27,2],[21,3],[8,3],[8,3],[11,5],[11,4],[17,3],[17,1],[36,1],[36,1],[36,1],[36,1],[36,1],[36,3],[47,1],[49,3],[35,1],[35,1],[35,1],[41,2],[30,1],[53,3],[53,1],[6,0],[6,2],[20,0],[20,1],[23,0],[23,1],[37,0],[37,1],[38,0],[38,1],[39,0],[39,2],[40,0],[40,1],[48,1],[48,2]],
1104   performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {
1105
1106   var $0 = $$.length - 1;
1107   switch (yystate) {
1108   case 1: yy.prepareProgram($$[$0-1].statements, true); return $$[$0-1]; 
1109   break;
1110   case 2:this.$ = new yy.ProgramNode(yy.prepareProgram($$[$0]), {}, this._$);
1111   break;
1112   case 3:this.$ = $$[$0];
1113   break;
1114   case 4:this.$ = $$[$0];
1115   break;
1116   case 5:this.$ = $$[$0];
1117   break;
1118   case 6:this.$ = $$[$0];
1119   break;
1120   case 7:this.$ = new yy.ContentNode($$[$0], this._$);
1121   break;
1122   case 8:this.$ = new yy.CommentNode($$[$0], this._$);
1123   break;
1124   case 9:this.$ = new yy.RawBlockNode($$[$0-2], $$[$0-1], $$[$0], this._$);
1125   break;
1126   case 10:this.$ = new yy.MustacheNode($$[$0-1], null, '', '', this._$);
1127   break;
1128   case 11:this.$ = yy.prepareBlock($$[$0-3], $$[$0-2], $$[$0-1], $$[$0], false, this._$);
1129   break;
1130   case 12:this.$ = yy.prepareBlock($$[$0-3], $$[$0-2], $$[$0-1], $$[$0], true, this._$);
1131   break;
1132   case 13:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], yy.stripFlags($$[$0-2], $$[$0]), this._$);
1133   break;
1134   case 14:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], yy.stripFlags($$[$0-2], $$[$0]), this._$);
1135   break;
1136   case 15:this.$ = { strip: yy.stripFlags($$[$0-1], $$[$0-1]), program: $$[$0] };
1137   break;
1138   case 16:this.$ = {path: $$[$0-1], strip: yy.stripFlags($$[$0-2], $$[$0])};
1139   break;
1140   case 17:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], yy.stripFlags($$[$0-2], $$[$0]), this._$);
1141   break;
1142   case 18:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], yy.stripFlags($$[$0-2], $$[$0]), this._$);
1143   break;
1144   case 19:this.$ = new yy.PartialNode($$[$0-3], $$[$0-2], $$[$0-1], yy.stripFlags($$[$0-4], $$[$0]), this._$);
1145   break;
1146   case 20:this.$ = new yy.PartialNode($$[$0-2], undefined, $$[$0-1], yy.stripFlags($$[$0-3], $$[$0]), this._$);
1147   break;
1148   case 21:this.$ = new yy.SexprNode([$$[$0-2]].concat($$[$0-1]), $$[$0], this._$);
1149   break;
1150   case 22:this.$ = new yy.SexprNode([$$[$0]], null, this._$);
1151   break;
1152   case 23:this.$ = $$[$0];
1153   break;
1154   case 24:this.$ = new yy.StringNode($$[$0], this._$);
1155   break;
1156   case 25:this.$ = new yy.NumberNode($$[$0], this._$);
1157   break;
1158   case 26:this.$ = new yy.BooleanNode($$[$0], this._$);
1159   break;
1160   case 27:this.$ = $$[$0];
1161   break;
1162   case 28:$$[$0-1].isHelper = true; this.$ = $$[$0-1];
1163   break;
1164   case 29:this.$ = new yy.HashNode($$[$0], this._$);
1165   break;
1166   case 30:this.$ = [$$[$0-2], $$[$0]];
1167   break;
1168   case 31:this.$ = new yy.PartialNameNode($$[$0], this._$);
1169   break;
1170   case 32:this.$ = new yy.PartialNameNode(new yy.StringNode($$[$0], this._$), this._$);
1171   break;
1172   case 33:this.$ = new yy.PartialNameNode(new yy.NumberNode($$[$0], this._$));
1173   break;
1174   case 34:this.$ = new yy.DataNode($$[$0], this._$);
1175   break;
1176   case 35:this.$ = new yy.IdNode($$[$0], this._$);
1177   break;
1178   case 36: $$[$0-2].push({part: $$[$0], separator: $$[$0-1]}); this.$ = $$[$0-2]; 
1179   break;
1180   case 37:this.$ = [{part: $$[$0]}];
1181   break;
1182   case 38:this.$ = [];
1183   break;
1184   case 39:$$[$0-1].push($$[$0]);
1185   break;
1186   case 48:this.$ = [];
1187   break;
1188   case 49:$$[$0-1].push($$[$0]);
1189   break;
1190   case 52:this.$ = [$$[$0]];
1191   break;
1192   case 53:$$[$0-1].push($$[$0]);
1193   break;
1194   }
1195   },
1196   table: [{3:1,4:2,5:[2,38],6:3,12:[2,38],13:[2,38],16:[2,38],24:[2,38],26:[2,38],31:[2,38],32:[2,38],34:[2,38]},{1:[3]},{5:[1,4]},{5:[2,2],7:5,8:6,9:7,10:8,11:9,12:[1,10],13:[1,11],14:16,16:[1,20],19:14,22:15,24:[1,18],26:[1,19],28:[2,2],29:[2,2],31:[1,12],32:[1,13],34:[1,17]},{1:[2,1]},{5:[2,39],12:[2,39],13:[2,39],16:[2,39],24:[2,39],26:[2,39],28:[2,39],29:[2,39],31:[2,39],32:[2,39],34:[2,39]},{5:[2,3],12:[2,3],13:[2,3],16:[2,3],24:[2,3],26:[2,3],28:[2,3],29:[2,3],31:[2,3],32:[2,3],34:[2,3]},{5:[2,4],12:[2,4],13:[2,4],16:[2,4],24:[2,4],26:[2,4],28:[2,4],29:[2,4],31:[2,4],32:[2,4],34:[2,4]},{5:[2,5],12:[2,5],13:[2,5],16:[2,5],24:[2,5],26:[2,5],28:[2,5],29:[2,5],31:[2,5],32:[2,5],34:[2,5]},{5:[2,6],12:[2,6],13:[2,6],16:[2,6],24:[2,6],26:[2,6],28:[2,6],29:[2,6],31:[2,6],32:[2,6],34:[2,6]},{5:[2,7],12:[2,7],13:[2,7],16:[2,7],24:[2,7],26:[2,7],28:[2,7],29:[2,7],31:[2,7],32:[2,7],34:[2,7]},{5:[2,8],12:[2,8],13:[2,8],16:[2,8],24:[2,8],26:[2,8],28:[2,8],29:[2,8],31:[2,8],32:[2,8],34:[2,8]},{17:21,30:22,41:23,50:[1,26],52:[1,25],53:24},{17:27,30:22,41:23,50:[1,26],52:[1,25],53:24},{4:28,6:3,12:[2,38],13:[2,38],16:[2,38],24:[2,38],26:[2,38],28:[2,38],29:[2,38],31:[2,38],32:[2,38],34:[2,38]},{4:29,6:3,12:[2,38],13:[2,38],16:[2,38],24:[2,38],26:[2,38],28:[2,38],29:[2,38],31:[2,38],32:[2,38],34:[2,38]},{12:[1,30]},{30:32,35:31,42:[1,33],43:[1,34],50:[1,26],53:24},{17:35,30:22,41:23,50:[1,26],52:[1,25],53:24},{17:36,30:22,41:23,50:[1,26],52:[1,25],53:24},{17:37,30:22,41:23,50:[1,26],52:[1,25],53:24},{25:[1,38]},{18:[2,48],25:[2,48],33:[2,48],39:39,42:[2,48],43:[2,48],44:[2,48],45:[2,48],46:[2,48],50:[2,48],52:[2,48]},{18:[2,22],25:[2,22],33:[2,22],46:[2,22]},{18:[2,35],25:[2,35],33:[2,35],42:[2,35],43:[2,35],44:[2,35],45:[2,35],46:[2,35],50:[2,35],52:[2,35],54:[1,40]},{30:41,50:[1,26],53:24},{18:[2,37],25:[2,37],33:[2,37],42:[2,37],43:[2,37],44:[2,37],45:[2,37],46:[2,37],50:[2,37],52:[2,37],54:[2,37]},{33:[1,42]},{20:43,27:44,28:[1,45],29:[2,40]},{23:46,27:47,28:[1,45],29:[2,42]},{15:[1,48]},{25:[2,46],30:51,36:49,38:50,41:55,42:[1,52],43:[1,53],44:[1,54],45:[1,56],47:57,48:58,49:60,50:[1,59],52:[1,25],53:24},{25:[2,31],42:[2,31],43:[2,31],44:[2,31],45:[2,31],50:[2,31],52:[2,31]},{25:[2,32],42:[2,32],43:[2,32],44:[2,32],45:[2,32],50:[2,32],52:[2,32]},{25:[2,33],42:[2,33],43:[2,33],44:[2,33],45:[2,33],50:[2,33],52:[2,33]},{25:[1,61]},{25:[1,62]},{18:[1,63]},{5:[2,17],12:[2,17],13:[2,17],16:[2,17],24:[2,17],26:[2,17],28:[2,17],29:[2,17],31:[2,17],32:[2,17],34:[2,17]},{18:[2,50],25:[2,50],30:51,33:[2,50],36:65,40:64,41:55,42:[1,52],43:[1,53],44:[1,54],45:[1,56],46:[2,50],47:66,48:58,49:60,50:[1,59],52:[1,25],53:24},{50:[1,67]},{18:[2,34],25:[2,34],33:[2,34],42:[2,34],43:[2,34],44:[2,34],45:[2,34],46:[2,34],50:[2,34],52:[2,34]},{5:[2,18],12:[2,18],13:[2,18],16:[2,18],24:[2,18],26:[2,18],28:[2,18],29:[2,18],31:[2,18],32:[2,18],34:[2,18]},{21:68,29:[1,69]},{29:[2,41]},{4:70,6:3,12:[2,38],13:[2,38],16:[2,38],24:[2,38],26:[2,38],29:[2,38],31:[2,38],32:[2,38],34:[2,38]},{21:71,29:[1,69]},{29:[2,43]},{5:[2,9],12:[2,9],13:[2,9],16:[2,9],24:[2,9],26:[2,9],28:[2,9],29:[2,9],31:[2,9],32:[2,9],34:[2,9]},{25:[2,44],37:72,47:73,48:58,49:60,50:[1,74]},{25:[1,75]},{18:[2,23],25:[2,23],33:[2,23],42:[2,23],43:[2,23],44:[2,23],45:[2,23],46:[2,23],50:[2,23],52:[2,23]},{18:[2,24],25:[2,24],33:[2,24],42:[2,24],43:[2,24],44:[2,24],45:[2,24],46:[2,24],50:[2,24],52:[2,24]},{18:[2,25],25:[2,25],33:[2,25],42:[2,25],43:[2,25],44:[2,25],45:[2,25],46:[2,25],50:[2,25],52:[2,25]},{18:[2,26],25:[2,26],33:[2,26],42:[2,26],43:[2,26],44:[2,26],45:[2,26],46:[2,26],50:[2,26],52:[2,26]},{18:[2,27],25:[2,27],33:[2,27],42:[2,27],43:[2,27],44:[2,27],45:[2,27],46:[2,27],50:[2,27],52:[2,27]},{17:76,30:22,41:23,50:[1,26],52:[1,25],53:24},{25:[2,47]},{18:[2,29],25:[2,29],33:[2,29],46:[2,29],49:77,50:[1,74]},{18:[2,37],25:[2,37],33:[2,37],42:[2,37],43:[2,37],44:[2,37],45:[2,37],46:[2,37],50:[2,37],51:[1,78],52:[2,37],54:[2,37]},{18:[2,52],25:[2,52],33:[2,52],46:[2,52],50:[2,52]},{12:[2,13],13:[2,13],16:[2,13],24:[2,13],26:[2,13],28:[2,13],29:[2,13],31:[2,13],32:[2,13],34:[2,13]},{12:[2,14],13:[2,14],16:[2,14],24:[2,14],26:[2,14],28:[2,14],29:[2,14],31:[2,14],32:[2,14],34:[2,14]},{12:[2,10]},{18:[2,21],25:[2,21],33:[2,21],46:[2,21]},{18:[2,49],25:[2,49],33:[2,49],42:[2,49],43:[2,49],44:[2,49],45:[2,49],46:[2,49],50:[2,49],52:[2,49]},{18:[2,51],25:[2,51],33:[2,51],46:[2,51]},{18:[2,36],25:[2,36],33:[2,36],42:[2,36],43:[2,36],44:[2,36],45:[2,36],46:[2,36],50:[2,36],52:[2,36],54:[2,36]},{5:[2,11],12:[2,11],13:[2,11],16:[2,11],24:[2,11],26:[2,11],28:[2,11],29:[2,11],31:[2,11],32:[2,11],34:[2,11]},{30:79,50:[1,26],53:24},{29:[2,15]},{5:[2,12],12:[2,12],13:[2,12],16:[2,12],24:[2,12],26:[2,12],28:[2,12],29:[2,12],31:[2,12],32:[2,12],34:[2,12]},{25:[1,80]},{25:[2,45]},{51:[1,78]},{5:[2,20],12:[2,20],13:[2,20],16:[2,20],24:[2,20],26:[2,20],28:[2,20],29:[2,20],31:[2,20],32:[2,20],34:[2,20]},{46:[1,81]},{18:[2,53],25:[2,53],33:[2,53],46:[2,53],50:[2,53]},{30:51,36:82,41:55,42:[1,52],43:[1,53],44:[1,54],45:[1,56],50:[1,26],52:[1,25],53:24},{25:[1,83]},{5:[2,19],12:[2,19],13:[2,19],16:[2,19],24:[2,19],26:[2,19],28:[2,19],29:[2,19],31:[2,19],32:[2,19],34:[2,19]},{18:[2,28],25:[2,28],33:[2,28],42:[2,28],43:[2,28],44:[2,28],45:[2,28],46:[2,28],50:[2,28],52:[2,28]},{18:[2,30],25:[2,30],33:[2,30],46:[2,30],50:[2,30]},{5:[2,16],12:[2,16],13:[2,16],16:[2,16],24:[2,16],26:[2,16],28:[2,16],29:[2,16],31:[2,16],32:[2,16],34:[2,16]}],
1197   defaultActions: {4:[2,1],44:[2,41],47:[2,43],57:[2,47],63:[2,10],70:[2,15],73:[2,45]},
1198   parseError: function parseError(str, hash) {
1199       throw new Error(str);
1200   },
1201   parse: function parse(input) {
1202       var self = this, stack = [0], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;
1203       this.lexer.setInput(input);
1204       this.lexer.yy = this.yy;
1205       this.yy.lexer = this.lexer;
1206       this.yy.parser = this;
1207       if (typeof this.lexer.yylloc == "undefined")
1208           this.lexer.yylloc = {};
1209       var yyloc = this.lexer.yylloc;
1210       lstack.push(yyloc);
1211       var ranges = this.lexer.options && this.lexer.options.ranges;
1212       if (typeof this.yy.parseError === "function")
1213           this.parseError = this.yy.parseError;
1214       function popStack(n) {
1215           stack.length = stack.length - 2 * n;
1216           vstack.length = vstack.length - n;
1217           lstack.length = lstack.length - n;
1218       }
1219       function lex() {
1220           var token;
1221           token = self.lexer.lex() || 1;
1222           if (typeof token !== "number") {
1223               token = self.symbols_[token] || token;
1224           }
1225           return token;
1226       }
1227       var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;
1228       while (true) {
1229           state = stack[stack.length - 1];
1230           if (this.defaultActions[state]) {
1231               action = this.defaultActions[state];
1232           } else {
1233               if (symbol === null || typeof symbol == "undefined") {
1234                   symbol = lex();
1235               }
1236               action = table[state] && table[state][symbol];
1237           }
1238           if (typeof action === "undefined" || !action.length || !action[0]) {
1239               var errStr = "";
1240               if (!recovering) {
1241                   expected = [];
1242                   for (p in table[state])
1243                       if (this.terminals_[p] && p > 2) {
1244                           expected.push("'" + this.terminals_[p] + "'");
1245                       }
1246                   if (this.lexer.showPosition) {
1247                       errStr = "Parse error on line " + (yylineno + 1) + ":\n" + this.lexer.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'";
1248                   } else {
1249                       errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == 1?"end of input":"'" + (this.terminals_[symbol] || symbol) + "'");
1250                   }
1251                   this.parseError(errStr, {text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected});
1252               }
1253           }
1254           if (action[0] instanceof Array && action.length > 1) {
1255               throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol);
1256           }
1257           switch (action[0]) {
1258           case 1:
1259               stack.push(symbol);
1260               vstack.push(this.lexer.yytext);
1261               lstack.push(this.lexer.yylloc);
1262               stack.push(action[1]);
1263               symbol = null;
1264               if (!preErrorSymbol) {
1265                   yyleng = this.lexer.yyleng;
1266                   yytext = this.lexer.yytext;
1267                   yylineno = this.lexer.yylineno;
1268                   yyloc = this.lexer.yylloc;
1269                   if (recovering > 0)
1270                       recovering--;
1271               } else {
1272                   symbol = preErrorSymbol;
1273                   preErrorSymbol = null;
1274               }
1275               break;
1276           case 2:
1277               len = this.productions_[action[1]][1];
1278               yyval.$ = vstack[vstack.length - len];
1279               yyval._$ = {first_line: lstack[lstack.length - (len || 1)].first_line, last_line: lstack[lstack.length - 1].last_line, first_column: lstack[lstack.length - (len || 1)].first_column, last_column: lstack[lstack.length - 1].last_column};
1280               if (ranges) {
1281                   yyval._$.range = [lstack[lstack.length - (len || 1)].range[0], lstack[lstack.length - 1].range[1]];
1282               }
1283               r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack);
1284               if (typeof r !== "undefined") {
1285                   return r;
1286               }
1287               if (len) {
1288                   stack = stack.slice(0, -1 * len * 2);
1289                   vstack = vstack.slice(0, -1 * len);
1290                   lstack = lstack.slice(0, -1 * len);
1291               }
1292               stack.push(this.productions_[action[1]][0]);
1293               vstack.push(yyval.$);
1294               lstack.push(yyval._$);
1295               newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
1296               stack.push(newState);
1297               break;
1298           case 3:
1299               return true;
1300           }
1301       }
1302       return true;
1303   }
1304   };
1305   /* Jison generated lexer */
1306   var lexer = (function(){
1307   var lexer = ({EOF:1,
1308   parseError:function parseError(str, hash) {
1309           if (this.yy.parser) {
1310               this.yy.parser.parseError(str, hash);
1311           } else {
1312               throw new Error(str);
1313           }
1314       },
1315   setInput:function (input) {
1316           this._input = input;
1317           this._more = this._less = this.done = false;
1318           this.yylineno = this.yyleng = 0;
1319           this.yytext = this.matched = this.match = '';
1320           this.conditionStack = ['INITIAL'];
1321           this.yylloc = {first_line:1,first_column:0,last_line:1,last_column:0};
1322           if (this.options.ranges) this.yylloc.range = [0,0];
1323           this.offset = 0;
1324           return this;
1325       },
1326   input:function () {
1327           var ch = this._input[0];
1328           this.yytext += ch;
1329           this.yyleng++;
1330           this.offset++;
1331           this.match += ch;
1332           this.matched += ch;
1333           var lines = ch.match(/(?:\r\n?|\n).*/g);
1334           if (lines) {
1335               this.yylineno++;
1336               this.yylloc.last_line++;
1337           } else {
1338               this.yylloc.last_column++;
1339           }
1340           if (this.options.ranges) this.yylloc.range[1]++;
1341
1342           this._input = this._input.slice(1);
1343           return ch;
1344       },
1345   unput:function (ch) {
1346           var len = ch.length;
1347           var lines = ch.split(/(?:\r\n?|\n)/g);
1348
1349           this._input = ch + this._input;
1350           this.yytext = this.yytext.substr(0, this.yytext.length-len-1);
1351           //this.yyleng -= len;
1352           this.offset -= len;
1353           var oldLines = this.match.split(/(?:\r\n?|\n)/g);
1354           this.match = this.match.substr(0, this.match.length-1);
1355           this.matched = this.matched.substr(0, this.matched.length-1);
1356
1357           if (lines.length-1) this.yylineno -= lines.length-1;
1358           var r = this.yylloc.range;
1359
1360           this.yylloc = {first_line: this.yylloc.first_line,
1361             last_line: this.yylineno+1,
1362             first_column: this.yylloc.first_column,
1363             last_column: lines ?
1364                 (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length:
1365                 this.yylloc.first_column - len
1366             };
1367
1368           if (this.options.ranges) {
1369               this.yylloc.range = [r[0], r[0] + this.yyleng - len];
1370           }
1371           return this;
1372       },
1373   more:function () {
1374           this._more = true;
1375           return this;
1376       },
1377   less:function (n) {
1378           this.unput(this.match.slice(n));
1379       },
1380   pastInput:function () {
1381           var past = this.matched.substr(0, this.matched.length - this.match.length);
1382           return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
1383       },
1384   upcomingInput:function () {
1385           var next = this.match;
1386           if (next.length < 20) {
1387               next += this._input.substr(0, 20-next.length);
1388           }
1389           return (next.substr(0,20)+(next.length > 20 ? '...':'')).replace(/\n/g, "");
1390       },
1391   showPosition:function () {
1392           var pre = this.pastInput();
1393           var c = new Array(pre.length + 1).join("-");
1394           return pre + this.upcomingInput() + "\n" + c+"^";
1395       },
1396   next:function () {
1397           if (this.done) {
1398               return this.EOF;
1399           }
1400           if (!this._input) this.done = true;
1401
1402           var token,
1403               match,
1404               tempMatch,
1405               index,
1406               col,
1407               lines;
1408           if (!this._more) {
1409               this.yytext = '';
1410               this.match = '';
1411           }
1412           var rules = this._currentRules();
1413           for (var i=0;i < rules.length; i++) {
1414               tempMatch = this._input.match(this.rules[rules[i]]);
1415               if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {
1416                   match = tempMatch;
1417                   index = i;
1418                   if (!this.options.flex) break;
1419               }
1420           }
1421           if (match) {
1422               lines = match[0].match(/(?:\r\n?|\n).*/g);
1423               if (lines) this.yylineno += lines.length;
1424               this.yylloc = {first_line: this.yylloc.last_line,
1425                              last_line: this.yylineno+1,
1426                              first_column: this.yylloc.last_column,
1427                              last_column: lines ? lines[lines.length-1].length-lines[lines.length-1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length};
1428               this.yytext += match[0];
1429               this.match += match[0];
1430               this.matches = match;
1431               this.yyleng = this.yytext.length;
1432               if (this.options.ranges) {
1433                   this.yylloc.range = [this.offset, this.offset += this.yyleng];
1434               }
1435               this._more = false;
1436               this._input = this._input.slice(match[0].length);
1437               this.matched += match[0];
1438               token = this.performAction.call(this, this.yy, this, rules[index],this.conditionStack[this.conditionStack.length-1]);
1439               if (this.done && this._input) this.done = false;
1440               if (token) return token;
1441               else return;
1442           }
1443           if (this._input === "") {
1444               return this.EOF;
1445           } else {
1446               return this.parseError('Lexical error on line '+(this.yylineno+1)+'. Unrecognized text.\n'+this.showPosition(),
1447                       {text: "", token: null, line: this.yylineno});
1448           }
1449       },
1450   lex:function lex() {
1451           var r = this.next();
1452           if (typeof r !== 'undefined') {
1453               return r;
1454           } else {
1455               return this.lex();
1456           }
1457       },
1458   begin:function begin(condition) {
1459           this.conditionStack.push(condition);
1460       },
1461   popState:function popState() {
1462           return this.conditionStack.pop();
1463       },
1464   _currentRules:function _currentRules() {
1465           return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules;
1466       },
1467   topState:function () {
1468           return this.conditionStack[this.conditionStack.length-2];
1469       },
1470   pushState:function begin(condition) {
1471           this.begin(condition);
1472       }});
1473   lexer.options = {};
1474   lexer.performAction = function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
1475
1476
1477   function strip(start, end) {
1478     return yy_.yytext = yy_.yytext.substr(start, yy_.yyleng-end);
1479   }
1480
1481
1482   var YYSTATE=YY_START
1483   switch($avoiding_name_collisions) {
1484   case 0:
1485                                      if(yy_.yytext.slice(-2) === "\\\\") {
1486                                        strip(0,1);
1487                                        this.begin("mu");
1488                                      } else if(yy_.yytext.slice(-1) === "\\") {
1489                                        strip(0,1);
1490                                        this.begin("emu");
1491                                      } else {
1492                                        this.begin("mu");
1493                                      }
1494                                      if(yy_.yytext) return 12;
1495                                    
1496   break;
1497   case 1:return 12;
1498   break;
1499   case 2:
1500                                      this.popState();
1501                                      return 12;
1502                                    
1503   break;
1504   case 3:
1505                                     yy_.yytext = yy_.yytext.substr(5, yy_.yyleng-9);
1506                                     this.popState();
1507                                     return 15;
1508                                    
1509   break;
1510   case 4: return 12; 
1511   break;
1512   case 5:strip(0,4); this.popState(); return 13;
1513   break;
1514   case 6:return 45;
1515   break;
1516   case 7:return 46;
1517   break;
1518   case 8: return 16; 
1519   break;
1520   case 9:
1521                                     this.popState();
1522                                     this.begin('raw');
1523                                     return 18;
1524                                    
1525   break;
1526   case 10:return 34;
1527   break;
1528   case 11:return 24;
1529   break;
1530   case 12:return 29;
1531   break;
1532   case 13:this.popState(); return 28;
1533   break;
1534   case 14:this.popState(); return 28;
1535   break;
1536   case 15:return 26;
1537   break;
1538   case 16:return 26;
1539   break;
1540   case 17:return 32;
1541   break;
1542   case 18:return 31;
1543   break;
1544   case 19:this.popState(); this.begin('com');
1545   break;
1546   case 20:strip(3,5); this.popState(); return 13;
1547   break;
1548   case 21:return 31;
1549   break;
1550   case 22:return 51;
1551   break;
1552   case 23:return 50;
1553   break;
1554   case 24:return 50;
1555   break;
1556   case 25:return 54;
1557   break;
1558   case 26:// ignore whitespace
1559   break;
1560   case 27:this.popState(); return 33;
1561   break;
1562   case 28:this.popState(); return 25;
1563   break;
1564   case 29:yy_.yytext = strip(1,2).replace(/\\"/g,'"'); return 42;
1565   break;
1566   case 30:yy_.yytext = strip(1,2).replace(/\\'/g,"'"); return 42;
1567   break;
1568   case 31:return 52;
1569   break;
1570   case 32:return 44;
1571   break;
1572   case 33:return 44;
1573   break;
1574   case 34:return 43;
1575   break;
1576   case 35:return 50;
1577   break;
1578   case 36:yy_.yytext = strip(1,2); return 50;
1579   break;
1580   case 37:return 'INVALID';
1581   break;
1582   case 38:return 5;
1583   break;
1584   }
1585   };
1586   lexer.rules = [/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|\\\{\{|\\\\\{\{|$)))/,/^(?:\{\{\{\{\/[^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=[=}\s\/.])\}\}\}\})/,/^(?:[^\x00]*?(?=(\{\{\{\{\/)))/,/^(?:[\s\S]*?--\}\})/,/^(?:\()/,/^(?:\))/,/^(?:\{\{\{\{)/,/^(?:\}\}\}\})/,/^(?:\{\{(~)?>)/,/^(?:\{\{(~)?#)/,/^(?:\{\{(~)?\/)/,/^(?:\{\{(~)?\^\s*(~)?\}\})/,/^(?:\{\{(~)?\s*else\s*(~)?\}\})/,/^(?:\{\{(~)?\^)/,/^(?:\{\{(~)?\s*else\b)/,/^(?:\{\{(~)?\{)/,/^(?:\{\{(~)?&)/,/^(?:\{\{!--)/,/^(?:\{\{![\s\S]*?\}\})/,/^(?:\{\{(~)?)/,/^(?:=)/,/^(?:\.\.)/,/^(?:\.(?=([=~}\s\/.)])))/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}(~)?\}\})/,/^(?:(~)?\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@)/,/^(?:true(?=([~}\s)])))/,/^(?:false(?=([~}\s)])))/,/^(?:-?[0-9]+(?:\.[0-9]+)?(?=([~}\s)])))/,/^(?:([^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=([=~}\s\/.)]))))/,/^(?:\[[^\]]*\])/,/^(?:.)/,/^(?:$)/];
1587   lexer.conditions = {"mu":{"rules":[6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38],"inclusive":false},"emu":{"rules":[2],"inclusive":false},"com":{"rules":[5],"inclusive":false},"raw":{"rules":[3,4],"inclusive":false},"INITIAL":{"rules":[0,1,38],"inclusive":true}};
1588   return lexer;})()
1589   parser.lexer = lexer;
1590   function Parser () { this.yy = {}; }Parser.prototype = parser;parser.Parser = Parser;
1591   return new Parser;
1592   })();__exports__ = handlebars;
1593   /* jshint ignore:end */
1594   return __exports__;
1595 })();
1596
1597 // handlebars/compiler/helpers.js
1598 var __module10__ = (function(__dependency1__) {
1599   "use strict";
1600   var __exports__ = {};
1601   var Exception = __dependency1__;
1602
1603   function stripFlags(open, close) {
1604     return {
1605       left: open.charAt(2) === '~',
1606       right: close.charAt(close.length-3) === '~'
1607     };
1608   }
1609
1610   __exports__.stripFlags = stripFlags;
1611   function prepareBlock(mustache, program, inverseAndProgram, close, inverted, locInfo) {
1612     /*jshint -W040 */
1613     if (mustache.sexpr.id.original !== close.path.original) {
1614       throw new Exception(mustache.sexpr.id.original + ' doesn\'t match ' + close.path.original, mustache);
1615     }
1616
1617     var inverse = inverseAndProgram && inverseAndProgram.program;
1618
1619     var strip = {
1620       left: mustache.strip.left,
1621       right: close.strip.right,
1622
1623       // Determine the standalone candiacy. Basically flag our content as being possibly standalone
1624       // so our parent can determine if we actually are standalone
1625       openStandalone: isNextWhitespace(program.statements),
1626       closeStandalone: isPrevWhitespace((inverse || program).statements)
1627     };
1628
1629     if (mustache.strip.right) {
1630       omitRight(program.statements, null, true);
1631     }
1632
1633     if (inverse) {
1634       var inverseStrip = inverseAndProgram.strip;
1635
1636       if (inverseStrip.left) {
1637         omitLeft(program.statements, null, true);
1638       }
1639       if (inverseStrip.right) {
1640         omitRight(inverse.statements, null, true);
1641       }
1642       if (close.strip.left) {
1643         omitLeft(inverse.statements, null, true);
1644       }
1645
1646       // Find standalone else statments
1647       if (isPrevWhitespace(program.statements)
1648           && isNextWhitespace(inverse.statements)) {
1649
1650         omitLeft(program.statements);
1651         omitRight(inverse.statements);
1652       }
1653     } else {
1654       if (close.strip.left) {
1655         omitLeft(program.statements, null, true);
1656       }
1657     }
1658
1659     if (inverted) {
1660       return new this.BlockNode(mustache, inverse, program, strip, locInfo);
1661     } else {
1662       return new this.BlockNode(mustache, program, inverse, strip, locInfo);
1663     }
1664   }
1665
1666   __exports__.prepareBlock = prepareBlock;
1667   function prepareProgram(statements, isRoot) {
1668     for (var i = 0, l = statements.length; i < l; i++) {
1669       var current = statements[i],
1670           strip = current.strip;
1671
1672       if (!strip) {
1673         continue;
1674       }
1675
1676       var _isPrevWhitespace = isPrevWhitespace(statements, i, isRoot, current.type === 'partial'),
1677           _isNextWhitespace = isNextWhitespace(statements, i, isRoot),
1678
1679           openStandalone = strip.openStandalone && _isPrevWhitespace,
1680           closeStandalone = strip.closeStandalone && _isNextWhitespace,
1681           inlineStandalone = strip.inlineStandalone && _isPrevWhitespace && _isNextWhitespace;
1682
1683       if (strip.right) {
1684         omitRight(statements, i, true);
1685       }
1686       if (strip.left) {
1687         omitLeft(statements, i, true);
1688       }
1689
1690       if (inlineStandalone) {
1691         omitRight(statements, i);
1692
1693         if (omitLeft(statements, i)) {
1694           // If we are on a standalone node, save the indent info for partials
1695           if (current.type === 'partial') {
1696             current.indent = (/([ \t]+$)/).exec(statements[i-1].original) ? RegExp.$1 : '';
1697           }
1698         }
1699       }
1700       if (openStandalone) {
1701         omitRight((current.program || current.inverse).statements);
1702
1703         // Strip out the previous content node if it's whitespace only
1704         omitLeft(statements, i);
1705       }
1706       if (closeStandalone) {
1707         // Always strip the next node
1708         omitRight(statements, i);
1709
1710         omitLeft((current.inverse || current.program).statements);
1711       }
1712     }
1713
1714     return statements;
1715   }
1716
1717   __exports__.prepareProgram = prepareProgram;function isPrevWhitespace(statements, i, isRoot) {
1718     if (i === undefined) {
1719       i = statements.length;
1720     }
1721
1722     // Nodes that end with newlines are considered whitespace (but are special
1723     // cased for strip operations)
1724     var prev = statements[i-1],
1725         sibling = statements[i-2];
1726     if (!prev) {
1727       return isRoot;
1728     }
1729
1730     if (prev.type === 'content') {
1731       return (sibling || !isRoot ? (/\r?\n\s*?$/) : (/(^|\r?\n)\s*?$/)).test(prev.original);
1732     }
1733   }
1734   function isNextWhitespace(statements, i, isRoot) {
1735     if (i === undefined) {
1736       i = -1;
1737     }
1738
1739     var next = statements[i+1],
1740         sibling = statements[i+2];
1741     if (!next) {
1742       return isRoot;
1743     }
1744
1745     if (next.type === 'content') {
1746       return (sibling || !isRoot ? (/^\s*?\r?\n/) : (/^\s*?(\r?\n|$)/)).test(next.original);
1747     }
1748   }
1749
1750   // Marks the node to the right of the position as omitted.
1751   // I.e. {{foo}}' ' will mark the ' ' node as omitted.
1752   //
1753   // If i is undefined, then the first child will be marked as such.
1754   //
1755   // If mulitple is truthy then all whitespace will be stripped out until non-whitespace
1756   // content is met.
1757   function omitRight(statements, i, multiple) {
1758     var current = statements[i == null ? 0 : i + 1];
1759     if (!current || current.type !== 'content' || (!multiple && current.rightStripped)) {
1760       return;
1761     }
1762
1763     var original = current.string;
1764     current.string = current.string.replace(multiple ? (/^\s+/) : (/^[ \t]*\r?\n?/), '');
1765     current.rightStripped = current.string !== original;
1766   }
1767
1768   // Marks the node to the left of the position as omitted.
1769   // I.e. ' '{{foo}} will mark the ' ' node as omitted.
1770   //
1771   // If i is undefined then the last child will be marked as such.
1772   //
1773   // If mulitple is truthy then all whitespace will be stripped out until non-whitespace
1774   // content is met.
1775   function omitLeft(statements, i, multiple) {
1776     var current = statements[i == null ? statements.length - 1 : i - 1];
1777     if (!current || current.type !== 'content' || (!multiple && current.leftStripped)) {
1778       return;
1779     }
1780
1781     // We omit the last node if it's whitespace only and not preceeded by a non-content node.
1782     var original = current.string;
1783     current.string = current.string.replace(multiple ? (/\s+$/) : (/[ \t]+$/), '');
1784     current.leftStripped = current.string !== original;
1785     return current.leftStripped;
1786   }
1787   return __exports__;
1788 })(__module5__);
1789
1790 // handlebars/compiler/base.js
1791 var __module8__ = (function(__dependency1__, __dependency2__, __dependency3__, __dependency4__) {
1792   "use strict";
1793   var __exports__ = {};
1794   var parser = __dependency1__;
1795   var AST = __dependency2__;
1796   var Helpers = __dependency3__;
1797   var extend = __dependency4__.extend;
1798
1799   __exports__.parser = parser;
1800
1801   var yy = {};
1802   extend(yy, Helpers, AST);
1803
1804   function parse(input) {
1805     // Just return if an already-compile AST was passed in.
1806     if (input.constructor === AST.ProgramNode) { return input; }
1807
1808     parser.yy = yy;
1809
1810     return parser.parse(input);
1811   }
1812
1813   __exports__.parse = parse;
1814   return __exports__;
1815 })(__module9__, __module7__, __module10__, __module3__);
1816
1817 // handlebars/compiler/compiler.js
1818 var __module11__ = (function(__dependency1__, __dependency2__) {
1819   "use strict";
1820   var __exports__ = {};
1821   var Exception = __dependency1__;
1822   var isArray = __dependency2__.isArray;
1823
1824   var slice = [].slice;
1825
1826   function Compiler() {}
1827
1828   __exports__.Compiler = Compiler;// the foundHelper register will disambiguate helper lookup from finding a
1829   // function in a context. This is necessary for mustache compatibility, which
1830   // requires that context functions in blocks are evaluated by blockHelperMissing,
1831   // and then proceed as if the resulting value was provided to blockHelperMissing.
1832
1833   Compiler.prototype = {
1834     compiler: Compiler,
1835
1836     equals: function(other) {
1837       var len = this.opcodes.length;
1838       if (other.opcodes.length !== len) {
1839         return false;
1840       }
1841
1842       for (var i = 0; i < len; i++) {
1843         var opcode = this.opcodes[i],
1844             otherOpcode = other.opcodes[i];
1845         if (opcode.opcode !== otherOpcode.opcode || !argEquals(opcode.args, otherOpcode.args)) {
1846           return false;
1847         }
1848       }
1849
1850       // We know that length is the same between the two arrays because they are directly tied
1851       // to the opcode behavior above.
1852       len = this.children.length;
1853       for (i = 0; i < len; i++) {
1854         if (!this.children[i].equals(other.children[i])) {
1855           return false;
1856         }
1857       }
1858
1859       return true;
1860     },
1861
1862     guid: 0,
1863
1864     compile: function(program, options) {
1865       this.opcodes = [];
1866       this.children = [];
1867       this.depths = {list: []};
1868       this.options = options;
1869       this.stringParams = options.stringParams;
1870       this.trackIds = options.trackIds;
1871
1872       // These changes will propagate to the other compiler components
1873       var knownHelpers = this.options.knownHelpers;
1874       this.options.knownHelpers = {
1875         'helperMissing': true,
1876         'blockHelperMissing': true,
1877         'each': true,
1878         'if': true,
1879         'unless': true,
1880         'with': true,
1881         'log': true,
1882         'lookup': true
1883       };
1884       if (knownHelpers) {
1885         for (var name in knownHelpers) {
1886           this.options.knownHelpers[name] = knownHelpers[name];
1887         }
1888       }
1889
1890       return this.accept(program);
1891     },
1892
1893     accept: function(node) {
1894       return this[node.type](node);
1895     },
1896
1897     program: function(program) {
1898       var statements = program.statements;
1899
1900       for(var i=0, l=statements.length; i<l; i++) {
1901         this.accept(statements[i]);
1902       }
1903       this.isSimple = l === 1;
1904
1905       this.depths.list = this.depths.list.sort(function(a, b) {
1906         return a - b;
1907       });
1908
1909       return this;
1910     },
1911
1912     compileProgram: function(program) {
1913       var result = new this.compiler().compile(program, this.options);
1914       var guid = this.guid++, depth;
1915
1916       this.usePartial = this.usePartial || result.usePartial;
1917
1918       this.children[guid] = result;
1919
1920       for(var i=0, l=result.depths.list.length; i<l; i++) {
1921         depth = result.depths.list[i];
1922
1923         if(depth < 2) { continue; }
1924         else { this.addDepth(depth - 1); }
1925       }
1926
1927       return guid;
1928     },
1929
1930     block: function(block) {
1931       var mustache = block.mustache,
1932           program = block.program,
1933           inverse = block.inverse;
1934
1935       if (program) {
1936         program = this.compileProgram(program);
1937       }
1938
1939       if (inverse) {
1940         inverse = this.compileProgram(inverse);
1941       }
1942
1943       var sexpr = mustache.sexpr;
1944       var type = this.classifySexpr(sexpr);
1945
1946       if (type === "helper") {
1947         this.helperSexpr(sexpr, program, inverse);
1948       } else if (type === "simple") {
1949         this.simpleSexpr(sexpr);
1950
1951         // now that the simple mustache is resolved, we need to
1952         // evaluate it by executing `blockHelperMissing`
1953         this.opcode('pushProgram', program);
1954         this.opcode('pushProgram', inverse);
1955         this.opcode('emptyHash');
1956         this.opcode('blockValue', sexpr.id.original);
1957       } else {
1958         this.ambiguousSexpr(sexpr, program, inverse);
1959
1960         // now that the simple mustache is resolved, we need to
1961         // evaluate it by executing `blockHelperMissing`
1962         this.opcode('pushProgram', program);
1963         this.opcode('pushProgram', inverse);
1964         this.opcode('emptyHash');
1965         this.opcode('ambiguousBlockValue');
1966       }
1967
1968       this.opcode('append');
1969     },
1970
1971     hash: function(hash) {
1972       var pairs = hash.pairs, i, l;
1973
1974       this.opcode('pushHash');
1975
1976       for(i=0, l=pairs.length; i<l; i++) {
1977         this.pushParam(pairs[i][1]);
1978       }
1979       while(i--) {
1980         this.opcode('assignToHash', pairs[i][0]);
1981       }
1982       this.opcode('popHash');
1983     },
1984
1985     partial: function(partial) {
1986       var partialName = partial.partialName;
1987       this.usePartial = true;
1988
1989       if (partial.hash) {
1990         this.accept(partial.hash);
1991       } else {
1992         this.opcode('push', 'undefined');
1993       }
1994
1995       if (partial.context) {
1996         this.accept(partial.context);
1997       } else {
1998         this.opcode('getContext', 0);
1999         this.opcode('pushContext');
2000       }
2001
2002       this.opcode('invokePartial', partialName.name, partial.indent || '');
2003       this.opcode('append');
2004     },
2005
2006     content: function(content) {
2007       if (content.string) {
2008         this.opcode('appendContent', content.string);
2009       }
2010     },
2011
2012     mustache: function(mustache) {
2013       this.sexpr(mustache.sexpr);
2014
2015       if(mustache.escaped && !this.options.noEscape) {
2016         this.opcode('appendEscaped');
2017       } else {
2018         this.opcode('append');
2019       }
2020     },
2021
2022     ambiguousSexpr: function(sexpr, program, inverse) {
2023       var id = sexpr.id,
2024           name = id.parts[0],
2025           isBlock = program != null || inverse != null;
2026
2027       this.opcode('getContext', id.depth);
2028
2029       this.opcode('pushProgram', program);
2030       this.opcode('pushProgram', inverse);
2031
2032       this.ID(id);
2033
2034       this.opcode('invokeAmbiguous', name, isBlock);
2035     },
2036
2037     simpleSexpr: function(sexpr) {
2038       var id = sexpr.id;
2039
2040       if (id.type === 'DATA') {
2041         this.DATA(id);
2042       } else if (id.parts.length) {
2043         this.ID(id);
2044       } else {
2045         // Simplified ID for `this`
2046         this.addDepth(id.depth);
2047         this.opcode('getContext', id.depth);
2048         this.opcode('pushContext');
2049       }
2050
2051       this.opcode('resolvePossibleLambda');
2052     },
2053
2054     helperSexpr: function(sexpr, program, inverse) {
2055       var params = this.setupFullMustacheParams(sexpr, program, inverse),
2056           id = sexpr.id,
2057           name = id.parts[0];
2058
2059       if (this.options.knownHelpers[name]) {
2060         this.opcode('invokeKnownHelper', params.length, name);
2061       } else if (this.options.knownHelpersOnly) {
2062         throw new Exception("You specified knownHelpersOnly, but used the unknown helper " + name, sexpr);
2063       } else {
2064         id.falsy = true;
2065
2066         this.ID(id);
2067         this.opcode('invokeHelper', params.length, id.original, id.isSimple);
2068       }
2069     },
2070
2071     sexpr: function(sexpr) {
2072       var type = this.classifySexpr(sexpr);
2073
2074       if (type === "simple") {
2075         this.simpleSexpr(sexpr);
2076       } else if (type === "helper") {
2077         this.helperSexpr(sexpr);
2078       } else {
2079         this.ambiguousSexpr(sexpr);
2080       }
2081     },
2082
2083     ID: function(id) {
2084       this.addDepth(id.depth);
2085       this.opcode('getContext', id.depth);
2086
2087       var name = id.parts[0];
2088       if (!name) {
2089         // Context reference, i.e. `{{foo .}}` or `{{foo ..}}`
2090         this.opcode('pushContext');
2091       } else {
2092         this.opcode('lookupOnContext', id.parts, id.falsy, id.isScoped);
2093       }
2094     },
2095
2096     DATA: function(data) {
2097       this.options.data = true;
2098       this.opcode('lookupData', data.id.depth, data.id.parts);
2099     },
2100
2101     STRING: function(string) {
2102       this.opcode('pushString', string.string);
2103     },
2104
2105     NUMBER: function(number) {
2106       this.opcode('pushLiteral', number.number);
2107     },
2108
2109     BOOLEAN: function(bool) {
2110       this.opcode('pushLiteral', bool.bool);
2111     },
2112
2113     comment: function() {},
2114
2115     // HELPERS
2116     opcode: function(name) {
2117       this.opcodes.push({ opcode: name, args: slice.call(arguments, 1) });
2118     },
2119
2120     addDepth: function(depth) {
2121       if(depth === 0) { return; }
2122
2123       if(!this.depths[depth]) {
2124         this.depths[depth] = true;
2125         this.depths.list.push(depth);
2126       }
2127     },
2128
2129     classifySexpr: function(sexpr) {
2130       var isHelper   = sexpr.isHelper;
2131       var isEligible = sexpr.eligibleHelper;
2132       var options    = this.options;
2133
2134       // if ambiguous, we can possibly resolve the ambiguity now
2135       // An eligible helper is one that does not have a complex path, i.e. `this.foo`, `../foo` etc.
2136       if (isEligible && !isHelper) {
2137         var name = sexpr.id.parts[0];
2138
2139         if (options.knownHelpers[name]) {
2140           isHelper = true;
2141         } else if (options.knownHelpersOnly) {
2142           isEligible = false;
2143         }
2144       }
2145
2146       if (isHelper) { return "helper"; }
2147       else if (isEligible) { return "ambiguous"; }
2148       else { return "simple"; }
2149     },
2150
2151     pushParams: function(params) {
2152       for(var i=0, l=params.length; i<l; i++) {
2153         this.pushParam(params[i]);
2154       }
2155     },
2156
2157     pushParam: function(val) {
2158       if (this.stringParams) {
2159         if(val.depth) {
2160           this.addDepth(val.depth);
2161         }
2162         this.opcode('getContext', val.depth || 0);
2163         this.opcode('pushStringParam', val.stringModeValue, val.type);
2164
2165         if (val.type === 'sexpr') {
2166           // Subexpressions get evaluated and passed in
2167           // in string params mode.
2168           this.sexpr(val);
2169         }
2170       } else {
2171         if (this.trackIds) {
2172           this.opcode('pushId', val.type, val.idName || val.stringModeValue);
2173         }
2174         this.accept(val);
2175       }
2176     },
2177
2178     setupFullMustacheParams: function(sexpr, program, inverse) {
2179       var params = sexpr.params;
2180       this.pushParams(params);
2181
2182       this.opcode('pushProgram', program);
2183       this.opcode('pushProgram', inverse);
2184
2185       if (sexpr.hash) {
2186         this.hash(sexpr.hash);
2187       } else {
2188         this.opcode('emptyHash');
2189       }
2190
2191       return params;
2192     }
2193   };
2194
2195   function precompile(input, options, env) {
2196     if (input == null || (typeof input !== 'string' && input.constructor !== env.AST.ProgramNode)) {
2197       throw new Exception("You must pass a string or Handlebars AST to Handlebars.precompile. You passed " + input);
2198     }
2199
2200     options = options || {};
2201     if (!('data' in options)) {
2202       options.data = true;
2203     }
2204     if (options.compat) {
2205       options.useDepths = true;
2206     }
2207
2208     var ast = env.parse(input);
2209     var environment = new env.Compiler().compile(ast, options);
2210     return new env.JavaScriptCompiler().compile(environment, options);
2211   }
2212
2213   __exports__.precompile = precompile;function compile(input, options, env) {
2214     if (input == null || (typeof input !== 'string' && input.constructor !== env.AST.ProgramNode)) {
2215       throw new Exception("You must pass a string or Handlebars AST to Handlebars.compile. You passed " + input);
2216     }
2217
2218     options = options || {};
2219
2220     if (!('data' in options)) {
2221       options.data = true;
2222     }
2223     if (options.compat) {
2224       options.useDepths = true;
2225     }
2226
2227     var compiled;
2228
2229     function compileInput() {
2230       var ast = env.parse(input);
2231       var environment = new env.Compiler().compile(ast, options);
2232       var templateSpec = new env.JavaScriptCompiler().compile(environment, options, undefined, true);
2233       return env.template(templateSpec);
2234     }
2235
2236     // Template is only compiled on first use and cached after that point.
2237     var ret = function(context, options) {
2238       if (!compiled) {
2239         compiled = compileInput();
2240       }
2241       return compiled.call(this, context, options);
2242     };
2243     ret._setup = function(options) {
2244       if (!compiled) {
2245         compiled = compileInput();
2246       }
2247       return compiled._setup(options);
2248     };
2249     ret._child = function(i, data, depths) {
2250       if (!compiled) {
2251         compiled = compileInput();
2252       }
2253       return compiled._child(i, data, depths);
2254     };
2255     return ret;
2256   }
2257
2258   __exports__.compile = compile;function argEquals(a, b) {
2259     if (a === b) {
2260       return true;
2261     }
2262
2263     if (isArray(a) && isArray(b) && a.length === b.length) {
2264       for (var i = 0; i < a.length; i++) {
2265         if (!argEquals(a[i], b[i])) {
2266           return false;
2267         }
2268       }
2269       return true;
2270     }
2271   }
2272   return __exports__;
2273 })(__module5__, __module3__);
2274
2275 // handlebars/compiler/javascript-compiler.js
2276 var __module12__ = (function(__dependency1__, __dependency2__) {
2277   "use strict";
2278   var __exports__;
2279   var COMPILER_REVISION = __dependency1__.COMPILER_REVISION;
2280   var REVISION_CHANGES = __dependency1__.REVISION_CHANGES;
2281   var Exception = __dependency2__;
2282
2283   function Literal(value) {
2284     this.value = value;
2285   }
2286
2287   function JavaScriptCompiler() {}
2288
2289   JavaScriptCompiler.prototype = {
2290     // PUBLIC API: You can override these methods in a subclass to provide
2291     // alternative compiled forms for name lookup and buffering semantics
2292     nameLookup: function(parent, name /* , type*/) {
2293       if (JavaScriptCompiler.isValidJavaScriptVariableName(name)) {
2294         return parent + "." + name;
2295       } else {
2296         return parent + "['" + name + "']";
2297       }
2298     },
2299     depthedLookup: function(name) {
2300       this.aliases.lookup = 'this.lookup';
2301
2302       return 'lookup(depths, "' + name + '")';
2303     },
2304
2305     compilerInfo: function() {
2306       var revision = COMPILER_REVISION,
2307           versions = REVISION_CHANGES[revision];
2308       return [revision, versions];
2309     },
2310
2311     appendToBuffer: function(string) {
2312       if (this.environment.isSimple) {
2313         return "return " + string + ";";
2314       } else {
2315         return {
2316           appendToBuffer: true,
2317           content: string,
2318           toString: function() { return "buffer += " + string + ";"; }
2319         };
2320       }
2321     },
2322
2323     initializeBuffer: function() {
2324       return this.quotedString("");
2325     },
2326
2327     namespace: "Handlebars",
2328     // END PUBLIC API
2329
2330     compile: function(environment, options, context, asObject) {
2331       this.environment = environment;
2332       this.options = options;
2333       this.stringParams = this.options.stringParams;
2334       this.trackIds = this.options.trackIds;
2335       this.precompile = !asObject;
2336
2337       this.name = this.environment.name;
2338       this.isChild = !!context;
2339       this.context = context || {
2340         programs: [],
2341         environments: []
2342       };
2343
2344       this.preamble();
2345
2346       this.stackSlot = 0;
2347       this.stackVars = [];
2348       this.aliases = {};
2349       this.registers = { list: [] };
2350       this.hashes = [];
2351       this.compileStack = [];
2352       this.inlineStack = [];
2353
2354       this.compileChildren(environment, options);
2355
2356       this.useDepths = this.useDepths || environment.depths.list.length || this.options.compat;
2357
2358       var opcodes = environment.opcodes,
2359           opcode,
2360           i,
2361           l;
2362
2363       for (i = 0, l = opcodes.length; i < l; i++) {
2364         opcode = opcodes[i];
2365
2366         this[opcode.opcode].apply(this, opcode.args);
2367       }
2368
2369       // Flush any trailing content that might be pending.
2370       this.pushSource('');
2371
2372       /* istanbul ignore next */
2373       if (this.stackSlot || this.inlineStack.length || this.compileStack.length) {
2374         throw new Exception('Compile completed with content left on stack');
2375       }
2376
2377       var fn = this.createFunctionContext(asObject);
2378       if (!this.isChild) {
2379         var ret = {
2380           compiler: this.compilerInfo(),
2381           main: fn
2382         };
2383         var programs = this.context.programs;
2384         for (i = 0, l = programs.length; i < l; i++) {
2385           if (programs[i]) {
2386             ret[i] = programs[i];
2387           }
2388         }
2389
2390         if (this.environment.usePartial) {
2391           ret.usePartial = true;
2392         }
2393         if (this.options.data) {
2394           ret.useData = true;
2395         }
2396         if (this.useDepths) {
2397           ret.useDepths = true;
2398         }
2399         if (this.options.compat) {
2400           ret.compat = true;
2401         }
2402
2403         if (!asObject) {
2404           ret.compiler = JSON.stringify(ret.compiler);
2405           ret = this.objectLiteral(ret);
2406         }
2407
2408         return ret;
2409       } else {
2410         return fn;
2411       }
2412     },
2413
2414     preamble: function() {
2415       // track the last context pushed into place to allow skipping the
2416       // getContext opcode when it would be a noop
2417       this.lastContext = 0;
2418       this.source = [];
2419     },
2420
2421     createFunctionContext: function(asObject) {
2422       var varDeclarations = '';
2423
2424       var locals = this.stackVars.concat(this.registers.list);
2425       if(locals.length > 0) {
2426         varDeclarations += ", " + locals.join(", ");
2427       }
2428
2429       // Generate minimizer alias mappings
2430       for (var alias in this.aliases) {
2431         if (this.aliases.hasOwnProperty(alias)) {
2432           varDeclarations += ', ' + alias + '=' + this.aliases[alias];
2433         }
2434       }
2435
2436       var params = ["depth0", "helpers", "partials", "data"];
2437
2438       if (this.useDepths) {
2439         params.push('depths');
2440       }
2441
2442       // Perform a second pass over the output to merge content when possible
2443       var source = this.mergeSource(varDeclarations);
2444
2445       if (asObject) {
2446         params.push(source);
2447
2448         return Function.apply(this, params);
2449       } else {
2450         return 'function(' + params.join(',') + ') {\n  ' + source + '}';
2451       }
2452     },
2453     mergeSource: function(varDeclarations) {
2454       var source = '',
2455           buffer,
2456           appendOnly = !this.forceBuffer,
2457           appendFirst;
2458
2459       for (var i = 0, len = this.source.length; i < len; i++) {
2460         var line = this.source[i];
2461         if (line.appendToBuffer) {
2462           if (buffer) {
2463             buffer = buffer + '\n    + ' + line.content;
2464           } else {
2465             buffer = line.content;
2466           }
2467         } else {
2468           if (buffer) {
2469             if (!source) {
2470               appendFirst = true;
2471               source = buffer + ';\n  ';
2472             } else {
2473               source += 'buffer += ' + buffer + ';\n  ';
2474             }
2475             buffer = undefined;
2476           }
2477           source += line + '\n  ';
2478
2479           if (!this.environment.isSimple) {
2480             appendOnly = false;
2481           }
2482         }
2483       }
2484
2485       if (appendOnly) {
2486         if (buffer || !source) {
2487           source += 'return ' + (buffer || '""') + ';\n';
2488         }
2489       } else {
2490         varDeclarations += ", buffer = " + (appendFirst ? '' : this.initializeBuffer());
2491         if (buffer) {
2492           source += 'return buffer + ' + buffer + ';\n';
2493         } else {
2494           source += 'return buffer;\n';
2495         }
2496       }
2497
2498       if (varDeclarations) {
2499         source = 'var ' + varDeclarations.substring(2) + (appendFirst ? '' : ';\n  ') + source;
2500       }
2501
2502       return source;
2503     },
2504
2505     // [blockValue]
2506     //
2507     // On stack, before: hash, inverse, program, value
2508     // On stack, after: return value of blockHelperMissing
2509     //
2510     // The purpose of this opcode is to take a block of the form
2511     // `{{#this.foo}}...{{/this.foo}}`, resolve the value of `foo`, and
2512     // replace it on the stack with the result of properly
2513     // invoking blockHelperMissing.
2514     blockValue: function(name) {
2515       this.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
2516
2517       var params = [this.contextName(0)];
2518       this.setupParams(name, 0, params);
2519
2520       var blockName = this.popStack();
2521       params.splice(1, 0, blockName);
2522
2523       this.push('blockHelperMissing.call(' + params.join(', ') + ')');
2524     },
2525
2526     // [ambiguousBlockValue]
2527     //
2528     // On stack, before: hash, inverse, program, value
2529     // Compiler value, before: lastHelper=value of last found helper, if any
2530     // On stack, after, if no lastHelper: same as [blockValue]
2531     // On stack, after, if lastHelper: value
2532     ambiguousBlockValue: function() {
2533       this.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
2534
2535       // We're being a bit cheeky and reusing the options value from the prior exec
2536       var params = [this.contextName(0)];
2537       this.setupParams('', 0, params, true);
2538
2539       this.flushInline();
2540
2541       var current = this.topStack();
2542       params.splice(1, 0, current);
2543
2544       this.pushSource("if (!" + this.lastHelper + ") { " + current + " = blockHelperMissing.call(" + params.join(", ") + "); }");
2545     },
2546
2547     // [appendContent]
2548     //
2549     // On stack, before: ...
2550     // On stack, after: ...
2551     //
2552     // Appends the string value of `content` to the current buffer
2553     appendContent: function(content) {
2554       if (this.pendingContent) {
2555         content = this.pendingContent + content;
2556       }
2557
2558       this.pendingContent = content;
2559     },
2560
2561     // [append]
2562     //
2563     // On stack, before: value, ...
2564     // On stack, after: ...
2565     //
2566     // Coerces `value` to a String and appends it to the current buffer.
2567     //
2568     // If `value` is truthy, or 0, it is coerced into a string and appended
2569     // Otherwise, the empty string is appended
2570     append: function() {
2571       // Force anything that is inlined onto the stack so we don't have duplication
2572       // when we examine local
2573       this.flushInline();
2574       var local = this.popStack();
2575       this.pushSource('if (' + local + ' != null) { ' + this.appendToBuffer(local) + ' }');
2576       if (this.environment.isSimple) {
2577         this.pushSource("else { " + this.appendToBuffer("''") + " }");
2578       }
2579     },
2580
2581     // [appendEscaped]
2582     //
2583     // On stack, before: value, ...
2584     // On stack, after: ...
2585     //
2586     // Escape `value` and append it to the buffer
2587     appendEscaped: function() {
2588       this.aliases.escapeExpression = 'this.escapeExpression';
2589
2590       this.pushSource(this.appendToBuffer("escapeExpression(" + this.popStack() + ")"));
2591     },
2592
2593     // [getContext]
2594     //
2595     // On stack, before: ...
2596     // On stack, after: ...
2597     // Compiler value, after: lastContext=depth
2598     //
2599     // Set the value of the `lastContext` compiler value to the depth
2600     getContext: function(depth) {
2601       this.lastContext = depth;
2602     },
2603
2604     // [pushContext]
2605     //
2606     // On stack, before: ...
2607     // On stack, after: currentContext, ...
2608     //
2609     // Pushes the value of the current context onto the stack.
2610     pushContext: function() {
2611       this.pushStackLiteral(this.contextName(this.lastContext));
2612     },
2613
2614     // [lookupOnContext]
2615     //
2616     // On stack, before: ...
2617     // On stack, after: currentContext[name], ...
2618     //
2619     // Looks up the value of `name` on the current context and pushes
2620     // it onto the stack.
2621     lookupOnContext: function(parts, falsy, scoped) {
2622       /*jshint -W083 */
2623       var i = 0,
2624           len = parts.length;
2625
2626       if (!scoped && this.options.compat && !this.lastContext) {
2627         // The depthed query is expected to handle the undefined logic for the root level that
2628         // is implemented below, so we evaluate that directly in compat mode
2629         this.push(this.depthedLookup(parts[i++]));
2630       } else {
2631         this.pushContext();
2632       }
2633
2634       for (; i < len; i++) {
2635         this.replaceStack(function(current) {
2636           var lookup = this.nameLookup(current, parts[i], 'context');
2637           // We want to ensure that zero and false are handled properly if the context (falsy flag)
2638           // needs to have the special handling for these values.
2639           if (!falsy) {
2640             return ' != null ? ' + lookup + ' : ' + current;
2641           } else {
2642             // Otherwise we can use generic falsy handling
2643             return ' && ' + lookup;
2644           }
2645         });
2646       }
2647     },
2648
2649     // [lookupData]
2650     //
2651     // On stack, before: ...
2652     // On stack, after: data, ...
2653     //
2654     // Push the data lookup operator
2655     lookupData: function(depth, parts) {
2656       /*jshint -W083 */
2657       if (!depth) {
2658         this.pushStackLiteral('data');
2659       } else {
2660         this.pushStackLiteral('this.data(data, ' + depth + ')');
2661       }
2662
2663       var len = parts.length;
2664       for (var i = 0; i < len; i++) {
2665         this.replaceStack(function(current) {
2666           return ' && ' + this.nameLookup(current, parts[i], 'data');
2667         });
2668       }
2669     },
2670
2671     // [resolvePossibleLambda]
2672     //
2673     // On stack, before: value, ...
2674     // On stack, after: resolved value, ...
2675     //
2676     // If the `value` is a lambda, replace it on the stack by
2677     // the return value of the lambda
2678     resolvePossibleLambda: function() {
2679       this.aliases.lambda = 'this.lambda';
2680
2681       this.push('lambda(' + this.popStack() + ', ' + this.contextName(0) + ')');
2682     },
2683
2684     // [pushStringParam]
2685     //
2686     // On stack, before: ...
2687     // On stack, after: string, currentContext, ...
2688     //
2689     // This opcode is designed for use in string mode, which
2690     // provides the string value of a parameter along with its
2691     // depth rather than resolving it immediately.
2692     pushStringParam: function(string, type) {
2693       this.pushContext();
2694       this.pushString(type);
2695
2696       // If it's a subexpression, the string result
2697       // will be pushed after this opcode.
2698       if (type !== 'sexpr') {
2699         if (typeof string === 'string') {
2700           this.pushString(string);
2701         } else {
2702           this.pushStackLiteral(string);
2703         }
2704       }
2705     },
2706
2707     emptyHash: function() {
2708       this.pushStackLiteral('{}');
2709
2710       if (this.trackIds) {
2711         this.push('{}'); // hashIds
2712       }
2713       if (this.stringParams) {
2714         this.push('{}'); // hashContexts
2715         this.push('{}'); // hashTypes
2716       }
2717     },
2718     pushHash: function() {
2719       if (this.hash) {
2720         this.hashes.push(this.hash);
2721       }
2722       this.hash = {values: [], types: [], contexts: [], ids: []};
2723     },
2724     popHash: function() {
2725       var hash = this.hash;
2726       this.hash = this.hashes.pop();
2727
2728       if (this.trackIds) {
2729         this.push('{' + hash.ids.join(',') + '}');
2730       }
2731       if (this.stringParams) {
2732         this.push('{' + hash.contexts.join(',') + '}');
2733         this.push('{' + hash.types.join(',') + '}');
2734       }
2735
2736       this.push('{\n    ' + hash.values.join(',\n    ') + '\n  }');
2737     },
2738
2739     // [pushString]
2740     //
2741     // On stack, before: ...
2742     // On stack, after: quotedString(string), ...
2743     //
2744     // Push a quoted version of `string` onto the stack
2745     pushString: function(string) {
2746       this.pushStackLiteral(this.quotedString(string));
2747     },
2748
2749     // [push]
2750     //
2751     // On stack, before: ...
2752     // On stack, after: expr, ...
2753     //
2754     // Push an expression onto the stack
2755     push: function(expr) {
2756       this.inlineStack.push(expr);
2757       return expr;
2758     },
2759
2760     // [pushLiteral]
2761     //
2762     // On stack, before: ...
2763     // On stack, after: value, ...
2764     //
2765     // Pushes a value onto the stack. This operation prevents
2766     // the compiler from creating a temporary variable to hold
2767     // it.
2768     pushLiteral: function(value) {
2769       this.pushStackLiteral(value);
2770     },
2771
2772     // [pushProgram]
2773     //
2774     // On stack, before: ...
2775     // On stack, after: program(guid), ...
2776     //
2777     // Push a program expression onto the stack. This takes
2778     // a compile-time guid and converts it into a runtime-accessible
2779     // expression.
2780     pushProgram: function(guid) {
2781       if (guid != null) {
2782         this.pushStackLiteral(this.programExpression(guid));
2783       } else {
2784         this.pushStackLiteral(null);
2785       }
2786     },
2787
2788     // [invokeHelper]
2789     //
2790     // On stack, before: hash, inverse, program, params..., ...
2791     // On stack, after: result of helper invocation
2792     //
2793     // Pops off the helper's parameters, invokes the helper,
2794     // and pushes the helper's return value onto the stack.
2795     //
2796     // If the helper is not found, `helperMissing` is called.
2797     invokeHelper: function(paramSize, name, isSimple) {
2798       this.aliases.helperMissing = 'helpers.helperMissing';
2799
2800       var nonHelper = this.popStack();
2801       var helper = this.setupHelper(paramSize, name);
2802
2803       var lookup = (isSimple ? helper.name + ' || ' : '') + nonHelper + ' || helperMissing';
2804       this.push('((' + lookup + ').call(' + helper.callParams + '))');
2805     },
2806
2807     // [invokeKnownHelper]
2808     //
2809     // On stack, before: hash, inverse, program, params..., ...
2810     // On stack, after: result of helper invocation
2811     //
2812     // This operation is used when the helper is known to exist,
2813     // so a `helperMissing` fallback is not required.
2814     invokeKnownHelper: function(paramSize, name) {
2815       var helper = this.setupHelper(paramSize, name);
2816       this.push(helper.name + ".call(" + helper.callParams + ")");
2817     },
2818
2819     // [invokeAmbiguous]
2820     //
2821     // On stack, before: hash, inverse, program, params..., ...
2822     // On stack, after: result of disambiguation
2823     //
2824     // This operation is used when an expression like `{{foo}}`
2825     // is provided, but we don't know at compile-time whether it
2826     // is a helper or a path.
2827     //
2828     // This operation emits more code than the other options,
2829     // and can be avoided by passing the `knownHelpers` and
2830     // `knownHelpersOnly` flags at compile-time.
2831     invokeAmbiguous: function(name, helperCall) {
2832       this.aliases.functionType = '"function"';
2833       this.aliases.helperMissing = 'helpers.helperMissing';
2834       this.useRegister('helper');
2835
2836       var nonHelper = this.popStack();
2837
2838       this.emptyHash();
2839       var helper = this.setupHelper(0, name, helperCall);
2840
2841       var helperName = this.lastHelper = this.nameLookup('helpers', name, 'helper');
2842
2843       this.push(
2844         '((helper = (helper = ' + helperName + ' || ' + nonHelper + ') != null ? helper : helperMissing'
2845           + (helper.paramsInit ? '),(' + helper.paramsInit : '') + '),'
2846         + '(typeof helper === functionType ? helper.call(' + helper.callParams + ') : helper))');
2847     },
2848
2849     // [invokePartial]
2850     //
2851     // On stack, before: context, ...
2852     // On stack after: result of partial invocation
2853     //
2854     // This operation pops off a context, invokes a partial with that context,
2855     // and pushes the result of the invocation back.
2856     invokePartial: function(name, indent) {
2857       var params = [this.nameLookup('partials', name, 'partial'), "'" + indent + "'", "'" + name + "'", this.popStack(), this.popStack(), "helpers", "partials"];
2858
2859       if (this.options.data) {
2860         params.push("data");
2861       } else if (this.options.compat) {
2862         params.push('undefined');
2863       }
2864       if (this.options.compat) {
2865         params.push('depths');
2866       }
2867
2868       this.push("this.invokePartial(" + params.join(", ") + ")");
2869     },
2870
2871     // [assignToHash]
2872     //
2873     // On stack, before: value, ..., hash, ...
2874     // On stack, after: ..., hash, ...
2875     //
2876     // Pops a value off the stack and assigns it to the current hash
2877     assignToHash: function(key) {
2878       var value = this.popStack(),
2879           context,
2880           type,
2881           id;
2882
2883       if (this.trackIds) {
2884         id = this.popStack();
2885       }
2886       if (this.stringParams) {
2887         type = this.popStack();
2888         context = this.popStack();
2889       }
2890
2891       var hash = this.hash;
2892       if (context) {
2893         hash.contexts.push("'" + key + "': " + context);
2894       }
2895       if (type) {
2896         hash.types.push("'" + key + "': " + type);
2897       }
2898       if (id) {
2899         hash.ids.push("'" + key + "': " + id);
2900       }
2901       hash.values.push("'" + key + "': (" + value + ")");
2902     },
2903
2904     pushId: function(type, name) {
2905       if (type === 'ID' || type === 'DATA') {
2906         this.pushString(name);
2907       } else if (type === 'sexpr') {
2908         this.pushStackLiteral('true');
2909       } else {
2910         this.pushStackLiteral('null');
2911       }
2912     },
2913
2914     // HELPERS
2915
2916     compiler: JavaScriptCompiler,
2917
2918     compileChildren: function(environment, options) {
2919       var children = environment.children, child, compiler;
2920
2921       for(var i=0, l=children.length; i<l; i++) {
2922         child = children[i];
2923         compiler = new this.compiler();
2924
2925         var index = this.matchExistingProgram(child);
2926
2927         if (index == null) {
2928           this.context.programs.push('');     // Placeholder to prevent name conflicts for nested children
2929           index = this.context.programs.length;
2930           child.index = index;
2931           child.name = 'program' + index;
2932           this.context.programs[index] = compiler.compile(child, options, this.context, !this.precompile);
2933           this.context.environments[index] = child;
2934
2935           this.useDepths = this.useDepths || compiler.useDepths;
2936         } else {
2937           child.index = index;
2938           child.name = 'program' + index;
2939         }
2940       }
2941     },
2942     matchExistingProgram: function(child) {
2943       for (var i = 0, len = this.context.environments.length; i < len; i++) {
2944         var environment = this.context.environments[i];
2945         if (environment && environment.equals(child)) {
2946           return i;
2947         }
2948       }
2949     },
2950
2951     programExpression: function(guid) {
2952       var child = this.environment.children[guid],
2953           depths = child.depths.list,
2954           useDepths = this.useDepths,
2955           depth;
2956
2957       var programParams = [child.index, 'data'];
2958
2959       if (useDepths) {
2960         programParams.push('depths');
2961       }
2962
2963       return 'this.program(' + programParams.join(', ') + ')';
2964     },
2965
2966     useRegister: function(name) {
2967       if(!this.registers[name]) {
2968         this.registers[name] = true;
2969         this.registers.list.push(name);
2970       }
2971     },
2972
2973     pushStackLiteral: function(item) {
2974       return this.push(new Literal(item));
2975     },
2976
2977     pushSource: function(source) {
2978       if (this.pendingContent) {
2979         this.source.push(this.appendToBuffer(this.quotedString(this.pendingContent)));
2980         this.pendingContent = undefined;
2981       }
2982
2983       if (source) {
2984         this.source.push(source);
2985       }
2986     },
2987
2988     pushStack: function(item) {
2989       this.flushInline();
2990
2991       var stack = this.incrStack();
2992       this.pushSource(stack + " = " + item + ";");
2993       this.compileStack.push(stack);
2994       return stack;
2995     },
2996
2997     replaceStack: function(callback) {
2998       var prefix = '',
2999           inline = this.isInline(),
3000           stack,
3001           createdStack,
3002           usedLiteral;
3003
3004       /* istanbul ignore next */
3005       if (!this.isInline()) {
3006         throw new Exception('replaceStack on non-inline');
3007       }
3008
3009       // We want to merge the inline statement into the replacement statement via ','
3010       var top = this.popStack(true);
3011
3012       if (top instanceof Literal) {
3013         // Literals do not need to be inlined
3014         prefix = stack = top.value;
3015         usedLiteral = true;
3016       } else {
3017         // Get or create the current stack name for use by the inline
3018         createdStack = !this.stackSlot;
3019         var name = !createdStack ? this.topStackName() : this.incrStack();
3020
3021         prefix = '(' + this.push(name) + ' = ' + top + ')';
3022         stack = this.topStack();
3023       }
3024
3025       var item = callback.call(this, stack);
3026
3027       if (!usedLiteral) {
3028         this.popStack();
3029       }
3030       if (createdStack) {
3031         this.stackSlot--;
3032       }
3033       this.push('(' + prefix + item + ')');
3034     },
3035
3036     incrStack: function() {
3037       this.stackSlot++;
3038       if(this.stackSlot > this.stackVars.length) { this.stackVars.push("stack" + this.stackSlot); }
3039       return this.topStackName();
3040     },
3041     topStackName: function() {
3042       return "stack" + this.stackSlot;
3043     },
3044     flushInline: function() {
3045       var inlineStack = this.inlineStack;
3046       if (inlineStack.length) {
3047         this.inlineStack = [];
3048         for (var i = 0, len = inlineStack.length; i < len; i++) {
3049           var entry = inlineStack[i];
3050           if (entry instanceof Literal) {
3051             this.compileStack.push(entry);
3052           } else {
3053             this.pushStack(entry);
3054           }
3055         }
3056       }
3057     },
3058     isInline: function() {
3059       return this.inlineStack.length;
3060     },
3061
3062     popStack: function(wrapped) {
3063       var inline = this.isInline(),
3064           item = (inline ? this.inlineStack : this.compileStack).pop();
3065
3066       if (!wrapped && (item instanceof Literal)) {
3067         return item.value;
3068       } else {
3069         if (!inline) {
3070           /* istanbul ignore next */
3071           if (!this.stackSlot) {
3072             throw new Exception('Invalid stack pop');
3073           }
3074           this.stackSlot--;
3075         }
3076         return item;
3077       }
3078     },
3079
3080     topStack: function() {
3081       var stack = (this.isInline() ? this.inlineStack : this.compileStack),
3082           item = stack[stack.length - 1];
3083
3084       if (item instanceof Literal) {
3085         return item.value;
3086       } else {
3087         return item;
3088       }
3089     },
3090
3091     contextName: function(context) {
3092       if (this.useDepths && context) {
3093         return 'depths[' + context + ']';
3094       } else {
3095         return 'depth' + context;
3096       }
3097     },
3098
3099     quotedString: function(str) {
3100       return '"' + str
3101         .replace(/\\/g, '\\\\')
3102         .replace(/"/g, '\\"')
3103         .replace(/\n/g, '\\n')
3104         .replace(/\r/g, '\\r')
3105         .replace(/\u2028/g, '\\u2028')   // Per Ecma-262 7.3 + 7.8.4
3106         .replace(/\u2029/g, '\\u2029') + '"';
3107     },
3108
3109     objectLiteral: function(obj) {
3110       var pairs = [];
3111
3112       for (var key in obj) {
3113         if (obj.hasOwnProperty(key)) {
3114           pairs.push(this.quotedString(key) + ':' + obj[key]);
3115         }
3116       }
3117
3118       return '{' + pairs.join(',') + '}';
3119     },
3120
3121     setupHelper: function(paramSize, name, blockHelper) {
3122       var params = [],
3123           paramsInit = this.setupParams(name, paramSize, params, blockHelper);
3124       var foundHelper = this.nameLookup('helpers', name, 'helper');
3125
3126       return {
3127         params: params,
3128         paramsInit: paramsInit,
3129         name: foundHelper,
3130         callParams: [this.contextName(0)].concat(params).join(", ")
3131       };
3132     },
3133
3134     setupOptions: function(helper, paramSize, params) {
3135       var options = {}, contexts = [], types = [], ids = [], param, inverse, program;
3136
3137       options.name = this.quotedString(helper);
3138       options.hash = this.popStack();
3139
3140       if (this.trackIds) {
3141         options.hashIds = this.popStack();
3142       }
3143       if (this.stringParams) {
3144         options.hashTypes = this.popStack();
3145         options.hashContexts = this.popStack();
3146       }
3147
3148       inverse = this.popStack();
3149       program = this.popStack();
3150
3151       // Avoid setting fn and inverse if neither are set. This allows
3152       // helpers to do a check for `if (options.fn)`
3153       if (program || inverse) {
3154         if (!program) {
3155           program = 'this.noop';
3156         }
3157
3158         if (!inverse) {
3159           inverse = 'this.noop';
3160         }
3161
3162         options.fn = program;
3163         options.inverse = inverse;
3164       }
3165
3166       // The parameters go on to the stack in order (making sure that they are evaluated in order)
3167       // so we need to pop them off the stack in reverse order
3168       var i = paramSize;
3169       while (i--) {
3170         param = this.popStack();
3171         params[i] = param;
3172
3173         if (this.trackIds) {
3174           ids[i] = this.popStack();
3175         }
3176         if (this.stringParams) {
3177           types[i] = this.popStack();
3178           contexts[i] = this.popStack();
3179         }
3180       }
3181
3182       if (this.trackIds) {
3183         options.ids = "[" + ids.join(",") + "]";
3184       }
3185       if (this.stringParams) {
3186         options.types = "[" + types.join(",") + "]";
3187         options.contexts = "[" + contexts.join(",") + "]";
3188       }
3189
3190       if (this.options.data) {
3191         options.data = "data";
3192       }
3193
3194       return options;
3195     },
3196
3197     // the params and contexts arguments are passed in arrays
3198     // to fill in
3199     setupParams: function(helperName, paramSize, params, useRegister) {
3200       var options = this.objectLiteral(this.setupOptions(helperName, paramSize, params));
3201
3202       if (useRegister) {
3203         this.useRegister('options');
3204         params.push('options');
3205         return 'options=' + options;
3206       } else {
3207         params.push(options);
3208         return '';
3209       }
3210     }
3211   };
3212
3213   var reservedWords = (
3214     "break else new var" +
3215     " case finally return void" +
3216     " catch for switch while" +
3217     " continue function this with" +
3218     " default if throw" +
3219     " delete in try" +
3220     " do instanceof typeof" +
3221     " abstract enum int short" +
3222     " boolean export interface static" +
3223     " byte extends long super" +
3224     " char final native synchronized" +
3225     " class float package throws" +
3226     " const goto private transient" +
3227     " debugger implements protected volatile" +
3228     " double import public let yield"
3229   ).split(" ");
3230
3231   var compilerWords = JavaScriptCompiler.RESERVED_WORDS = {};
3232
3233   for(var i=0, l=reservedWords.length; i<l; i++) {
3234     compilerWords[reservedWords[i]] = true;
3235   }
3236
3237   JavaScriptCompiler.isValidJavaScriptVariableName = function(name) {
3238     return !JavaScriptCompiler.RESERVED_WORDS[name] && /^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name);
3239   };
3240
3241   __exports__ = JavaScriptCompiler;
3242   return __exports__;
3243 })(__module2__, __module5__);
3244
3245 // handlebars.js
3246 var __module0__ = (function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__) {
3247   "use strict";
3248   var __exports__;
3249   /*globals Handlebars: true */
3250   var Handlebars = __dependency1__;
3251
3252   // Compiler imports
3253   var AST = __dependency2__;
3254   var Parser = __dependency3__.parser;
3255   var parse = __dependency3__.parse;
3256   var Compiler = __dependency4__.Compiler;
3257   var compile = __dependency4__.compile;
3258   var precompile = __dependency4__.precompile;
3259   var JavaScriptCompiler = __dependency5__;
3260
3261   var _create = Handlebars.create;
3262   var create = function() {
3263     var hb = _create();
3264
3265     hb.compile = function(input, options) {
3266       return compile(input, options, hb);
3267     };
3268     hb.precompile = function (input, options) {
3269       return precompile(input, options, hb);
3270     };
3271
3272     hb.AST = AST;
3273     hb.Compiler = Compiler;
3274     hb.JavaScriptCompiler = JavaScriptCompiler;
3275     hb.Parser = Parser;
3276     hb.parse = parse;
3277
3278     return hb;
3279   };
3280
3281   Handlebars = create();
3282   Handlebars.create = create;
3283
3284   Handlebars['default'] = Handlebars;
3285
3286   __exports__ = Handlebars;
3287   return __exports__;
3288 })(__module1__, __module7__, __module8__, __module11__, __module12__);
3289
3290   return __module0__;
3291 }));
3292 /*
3293  * $Id$
3294 ** pz2.js - pazpar2's javascript client library.
3295 */
3296
3297 //since explorer is flawed
3298 if (!window['Node']) {
3299     window.Node = new Object();
3300     Node.ELEMENT_NODE = 1;
3301     Node.ATTRIBUTE_NODE = 2;
3302     Node.TEXT_NODE = 3;
3303     Node.CDATA_SECTION_NODE = 4;
3304     Node.ENTITY_REFERENCE_NODE = 5;
3305     Node.ENTITY_NODE = 6;
3306     Node.PROCESSING_INSTRUCTION_NODE = 7;
3307     Node.COMMENT_NODE = 8;
3308     Node.DOCUMENT_NODE = 9;
3309     Node.DOCUMENT_TYPE_NODE = 10;
3310     Node.DOCUMENT_FRAGMENT_NODE = 11;
3311     Node.NOTATION_NODE = 12;
3312 }
3313
3314 // prevent execution of more than once
3315 if(typeof window.pz2 == "undefined") {
3316 window.undefined = window.undefined;
3317
3318 var pz2 = function ( paramArray )
3319 {
3320     
3321     // at least one callback required
3322     if ( !paramArray )
3323         throw new Error("Pz2.js: Array with parameters has to be supplied."); 
3324
3325     //supported pazpar2's protocol version
3326     this.windowid = paramArray.windowid || window.name;
3327     this.suppProtoVer = '1';
3328     if (typeof paramArray.pazpar2path != "undefined")
3329         this.pz2String = paramArray.pazpar2path;
3330     else
3331         this.pz2String = "/pazpar2/search.pz2";
3332     this.useSessions = true;
3333     
3334     this.stylesheet = paramArray.detailstylesheet || null;
3335     //load stylesheet if required in async mode
3336     if( this.stylesheet ) {
3337         var context = this;
3338         var request = new pzHttpRequest( this.stylesheet );
3339         request.get( {}, function ( doc ) { context.xslDoc = doc; } );
3340     }
3341     
3342     this.errorHandler = paramArray.errorhandler || null;
3343     this.showResponseType = paramArray.showResponseType || "xml";
3344     
3345     // function callbacks
3346     this.initCallback = paramArray.oninit || null;
3347     this.statCallback = paramArray.onstat || null;
3348     this.showCallback = paramArray.onshow || null;
3349     this.termlistCallback = paramArray.onterm || null;
3350     this.recordCallback = paramArray.onrecord || null;
3351     this.bytargetCallback = paramArray.onbytarget || null;
3352     this.resetCallback = paramArray.onreset || null;
3353
3354     // termlist keys
3355     this.termKeys = paramArray.termlist || "subject";
3356     
3357     // some configurational stuff
3358     this.keepAlive = 50000;
3359     
3360     if ( paramArray.keepAlive < this.keepAlive )
3361         this.keepAlive = paramArray.keepAlive;
3362
3363     this.sessionID = null;
3364     this.serviceId = paramArray.serviceId || null;
3365     this.initStatusOK = false;
3366     this.pingStatusOK = false;
3367     this.searchStatusOK = false;
3368     this.mergekey = paramArray.mergekey || null;
3369     this.rank = paramArray.rank || null;
3370     
3371     // for sorting
3372     this.currentSort = "relevance";
3373
3374     // where are we?
3375     this.currentStart = 0;
3376     // currentNum can be overwritten in show 
3377     this.currentNum = 20;
3378
3379     // last full record retrieved
3380     this.currRecID = null;
3381     
3382     // current query
3383     this.currQuery = null;
3384
3385     //current raw record offset
3386     this.currRecOffset = null;
3387
3388     //timers
3389     this.pingTimer = null;
3390     this.statTime = paramArray.stattime || 1000;
3391     this.statTimer = null;
3392     this.termTime = paramArray.termtime || 1000;
3393     this.termTimer = null;
3394     this.showTime = paramArray.showtime || 1000;
3395     this.showTimer = null;
3396     this.showFastCount = 4;
3397     this.bytargetTime = paramArray.bytargettime || 1000;
3398     this.bytargetTimer = null;
3399     this.recordTime = paramArray.recordtime || 500;
3400     this.recordTimer = null;
3401
3402     // counters for each command and applied delay
3403     this.dumpFactor = 500;
3404     this.showCounter = 0;
3405     this.termCounter = 0;
3406     this.statCounter = 0;
3407     this.bytargetCounter = 0;
3408     this.recordCounter = 0;
3409
3410     // active clients, updated by stat and show
3411     // might be an issue since bytarget will poll accordingly
3412     this.activeClients = 1;
3413
3414     // if in proxy mode no need to init
3415     if (paramArray.usesessions != undefined) {
3416          this.useSessions = paramArray.usesessions;
3417         this.initStatusOK = true;
3418     }
3419     // else, auto init session or wait for a user init?
3420     if (this.useSessions && paramArray.autoInit !== false) {
3421         this.init(this.sessionID, this.serviceId);
3422     }
3423     // Version parameter
3424     this.version = paramArray.version || null;
3425 };
3426
3427 pz2.prototype = 
3428 {
3429     //error handler for async error throws
3430    throwError: function (errMsg, errCode)
3431    {
3432         var err = new Error(errMsg);
3433         if (errCode) err.code = errCode;
3434                 
3435         if (this.errorHandler) {
3436             this.errorHandler(err);
3437         }
3438         else {
3439             throw err;
3440         }
3441    },
3442
3443     // stop activity by clearing tiemouts 
3444    stop: function ()
3445    {
3446        clearTimeout(this.statTimer);
3447        clearTimeout(this.showTimer);
3448        clearTimeout(this.termTimer);
3449        clearTimeout(this.bytargetTimer);
3450     },
3451     
3452     // reset status variables
3453     reset: function ()
3454     {   
3455         if ( this.useSessions ) {
3456             this.sessionID = null;
3457             this.initStatusOK = false;
3458             this.pingStatusOK = false;
3459             clearTimeout(this.pingTimer);
3460         }
3461         this.searchStatusOK = false;
3462         this.stop();
3463             
3464         if ( this.resetCallback )
3465                 this.resetCallback(this.windowid);
3466     },
3467
3468     init: function (sessionId, serviceId) 
3469     {
3470         this.reset();
3471         
3472         // session id as a param
3473         if (sessionId && this.useSessions ) {
3474             this.initStatusOK = true;
3475             this.sessionID = sessionId;
3476             this.ping();
3477         // old school direct pazpar2 init
3478         } else if (this.useSessions) {
3479             var context = this;
3480             var request = new pzHttpRequest(this.pz2String, this.errorHandler);
3481             var opts = {'command' : 'init'};
3482             if (serviceId) opts.service = serviceId;
3483             request.safeGet(
3484                 opts,
3485                 function(data) {
3486                     if ( data.getElementsByTagName("status")[0]
3487                             .childNodes[0].nodeValue == "OK" ) {
3488                         if ( data.getElementsByTagName("protocol")[0]
3489                                 .childNodes[0].nodeValue 
3490                             != context.suppProtoVer )
3491                             throw new Error(
3492                                 "Server's protocol not supported by the client"
3493                             );
3494                         context.initStatusOK = true;
3495                         context.sessionID = 
3496                             data.getElementsByTagName("session")[0]
3497                                 .childNodes[0].nodeValue;
3498                         if (data.getElementsByTagName("keepAlive").length > 0) {
3499                             context.keepAlive = data.getElementsByTagName("keepAlive")[0].childNodes[0].nodeValue;
3500                         }
3501                         context.pingTimer =
3502                             setTimeout(
3503                                 function () {
3504                                     context.ping();
3505                                 },
3506                                 context.keepAlive
3507                             );
3508                         if ( context.initCallback )
3509                             context.initCallback(context.windowid);
3510                     }
3511                     else
3512                         context.throwError('Init failed. Malformed WS resonse.',
3513                                             110);
3514                 }
3515             );
3516         // when through proxy no need to init
3517         } else {
3518             this.initStatusOK = true;
3519         }
3520     },
3521     // no need to ping explicitly
3522     ping: function () 
3523     {
3524         // pinging only makes sense when using pazpar2 directly
3525         if( !this.initStatusOK || !this.useSessions )
3526             throw new Error(
3527             'Pz2.js: Ping not allowed (proxy mode) or session not initialized.'
3528             );
3529         var context = this;
3530
3531         clearTimeout(context.pingTimer);
3532
3533         var request = new pzHttpRequest(this.pz2String, this.errorHandler);
3534         request.safeGet(
3535             { "command": "ping", "session": this.sessionID, "windowid" : context.windowid },
3536             function(data) {
3537                 if ( data.getElementsByTagName("status")[0]
3538                         .childNodes[0].nodeValue == "OK" ) {
3539                     context.pingStatusOK = true;
3540                     context.pingTimer =
3541                         setTimeout(
3542                             function () {
3543                                 context.ping();
3544                             },
3545                             context.keepAlive
3546                         );
3547                 }
3548                 else
3549                     context.throwError('Ping failed. Malformed WS resonse.',
3550                                         111);
3551             }
3552         );
3553     },
3554     search: function (query, num, sort, filter, showfrom, addParamsArr)
3555     {
3556         clearTimeout(this.statTimer);
3557         clearTimeout(this.showTimer);
3558         clearTimeout(this.termTimer);
3559         clearTimeout(this.bytargetTimer);
3560         
3561         this.showCounter = 0;
3562         this.termCounter = 0;
3563         this.bytargetCounter = 0;
3564         this.statCounter = 0;
3565         this.activeClients = 1;
3566         
3567         // no proxy mode
3568         if( !this.initStatusOK )
3569             throw new Error('Pz2.js: session not initialized.');
3570         
3571         if( query !== undefined )
3572             this.currQuery = query;
3573         else
3574             throw new Error("Pz2.js: no query supplied to the search command.");
3575         
3576         if ( showfrom !== undefined )
3577             var start = showfrom;
3578         else
3579             var start = 0;
3580
3581         var searchParams = { 
3582           "command": "search",
3583           "query": this.currQuery, 
3584           "session": this.sessionID,
3585           "windowid" : this.windowid
3586         };
3587         
3588         if( sort !== undefined ) {
3589             this.currentSort = sort;
3590             searchParams["sort"] = sort;
3591         }
3592         if (filter !== undefined) searchParams["filter"] = filter;
3593         if (this.mergekey) searchParams["mergekey"] = this.mergekey;
3594         if (this.rank) searchParams["rank"] = this.rank;
3595
3596         // copy additional parmeters, do not overwrite
3597         if (addParamsArr != undefined) {
3598             for (var prop in addParamsArr) {
3599                 if (!searchParams.hasOwnProperty(prop))
3600                     searchParams[prop] = addParamsArr[prop];
3601             }
3602         }
3603         
3604         var context = this;
3605         var request = new pzHttpRequest(this.pz2String, this.errorHandler);
3606         request.safeGet(
3607             searchParams,
3608             function(data) {
3609                 if ( data.getElementsByTagName("status")[0]
3610                         .childNodes[0].nodeValue == "OK" ) {
3611                     context.searchStatusOK = true;
3612                     //piggyback search
3613                     if (context.showCallback)
3614                         context.show(start, num, sort);
3615                     if (context.statCallback)
3616                         context.stat();
3617                     if (context.termlistCallback)
3618                         context.termlist();
3619                     if (context.bytargetCallback)
3620                         context.bytarget();
3621                 }
3622                 else
3623                     context.throwError('Search failed. Malformed WS resonse.',
3624                                         112);
3625             }
3626         );
3627     },
3628     stat: function()
3629     {
3630         if( !this.initStatusOK )
3631             throw new Error('Pz2.js: session not initialized.');
3632         
3633         // if called explicitly takes precedence
3634         clearTimeout(this.statTimer);
3635         
3636         var context = this;
3637         var request = new pzHttpRequest(this.pz2String, this.errorHandler);
3638         request.safeGet(
3639             { "command": "stat", "session": this.sessionID, "windowid" : context.windowid },
3640             function(data) {
3641                 if ( data.getElementsByTagName("stat") ) {
3642                     var activeClients = 
3643                         Number( data.getElementsByTagName("activeclients")[0]
3644                                     .childNodes[0].nodeValue );
3645                     context.activeClients = activeClients;
3646
3647                     var stat = Element_parseChildNodes(data.documentElement);
3648
3649                     context.statCounter++;
3650                     var delay = context.statTime 
3651                         + context.statCounter * context.dumpFactor;
3652                     
3653                     if ( activeClients > 0 )
3654                         context.statTimer = 
3655                             setTimeout( 
3656                                 function () {
3657                                     context.stat();
3658                                 },
3659                                 delay
3660                             );
3661                     context.statCallback(stat, context.windowid);
3662                 }
3663                 else
3664                     context.throwError('Stat failed. Malformed WS resonse.',
3665                                         113);
3666             }
3667         );
3668     },
3669     show: function(start, num, sort, query_state)
3670     {
3671         if( !this.searchStatusOK && this.useSessions )
3672             throw new Error(
3673                 'Pz2.js: show command has to be preceded with a search command.'
3674             );
3675         
3676         // if called explicitly takes precedence
3677         clearTimeout(this.showTimer);
3678         
3679         if( sort !== undefined )
3680             this.currentSort = sort;
3681         if( start !== undefined )
3682             this.currentStart = Number( start );
3683         if( num !== undefined )
3684             this.currentNum = Number( num );
3685
3686         var context = this;
3687         var request = new pzHttpRequest(this.pz2String, this.errorHandler);
3688         var requestParameters = 
3689           {
3690               "command": "show", 
3691               "session": this.sessionID, 
3692               "start": this.currentStart,
3693               "num": this.currentNum, 
3694               "sort": this.currentSort, 
3695               "block": 1,
3696               "type": this.showResponseType,
3697               "windowid" : this.windowid
3698           };
3699         if (query_state)
3700           requestParameters["query-state"] = query_state;
3701         if (this.version && this.version > 0)
3702             requestParameters["version"] = this.version;
3703         request.safeGet(
3704           requestParameters,
3705           function(data, type) {
3706             var show = null;
3707             var activeClients = 0;
3708             if (type === "json") {
3709               show = {};
3710               activeClients = Number(data.activeclients[0]);
3711               show.activeclients = activeClients;
3712               show.merged = Number(data.merged[0]);
3713               show.total = Number(data.total[0]);
3714               show.start = Number(data.start[0]);
3715               show.num = Number(data.num[0]);
3716               show.hits = data.hit;
3717             } else if (data.getElementsByTagName("status")[0]
3718                   .childNodes[0].nodeValue == "OK") {
3719                 // first parse the status data send along with records
3720                 // this is strictly bound to the format
3721                 activeClients = 
3722                   Number(data.getElementsByTagName("activeclients")[0]
3723                       .childNodes[0].nodeValue);
3724                 show = {
3725                   "activeclients": activeClients,
3726                   "merged": 
3727                     Number( data.getElementsByTagName("merged")[0]
3728                         .childNodes[0].nodeValue ),
3729                   "total": 
3730                     Number( data.getElementsByTagName("total")[0]
3731                         .childNodes[0].nodeValue ),
3732                   "start": 
3733                     Number( data.getElementsByTagName("start")[0]
3734                         .childNodes[0].nodeValue ),
3735                   "num": 
3736                     Number( data.getElementsByTagName("num")[0]
3737                         .childNodes[0].nodeValue ),
3738                   "hits": []
3739                 };
3740                 // parse all the first-level nodes for all <hit> tags
3741                 var hits = data.getElementsByTagName("hit");
3742                 for (i = 0; i < hits.length; i++)
3743                   show.hits[i] = Element_parseChildNodes(hits[i]);
3744             } else {
3745               context.throwError('Show failed. Malformed WS resonse.',
3746                   114);
3747             };
3748             
3749             var approxNode = data.getElementsByTagName("approximation");
3750             if (approxNode && approxNode[0] && approxNode[0].childNodes[0] && approxNode[0].childNodes[0].nodeValue)
3751                 show['approximation'] = 
3752                   Number( approxNode[0].childNodes[0].nodeValue);
3753               
3754
3755               data.getElementsByTagName("")
3756             context.activeClients = activeClients; 
3757             context.showCounter++;
3758             var delay = context.showTime;
3759             if (context.showCounter > context.showFastCount)
3760               delay += context.showCounter * context.dumpFactor;
3761             if ( activeClients > 0 )
3762               context.showTimer = setTimeout(
3763                 function () {
3764                   context.show();
3765                 }, 
3766                 delay);
3767               context.showCallback(show, context.windowid);
3768           }
3769         );
3770     },
3771     record: function(id, offset, syntax, handler)
3772     {
3773         // we may call record with no previous search if in proxy mode
3774         if(!this.searchStatusOK && this.useSessions)
3775            throw new Error(
3776             'Pz2.js: record command has to be preceded with a search command.'
3777             );
3778         
3779         if( id !== undefined )
3780             this.currRecID = id;
3781         
3782         var recordParams = { 
3783             "command": "record", 
3784             "session": this.sessionID,
3785             "id": this.currRecID,
3786             "windowid" : this.windowid
3787         };
3788         
3789         this.currRecOffset = null;
3790         if (offset != undefined) {
3791             recordParams["offset"] = offset;
3792             this.currRecOffset = offset;
3793         }
3794
3795         if (syntax != undefined)
3796             recordParams['syntax'] = syntax;
3797
3798         //overwrite default callback id needed
3799         var callback = this.recordCallback;
3800         var args = undefined;
3801         if (handler != undefined) {
3802             callback = handler['callback'];
3803             args = handler['args'];
3804         }
3805         
3806         var context = this;
3807         var request = new pzHttpRequest(this.pz2String, this.errorHandler);
3808
3809         request.safeGet(
3810             recordParams,
3811             function(data) {
3812                 var recordNode;
3813                 var record;                                
3814                 //raw record
3815                 if (context.currRecOffset !== null) {
3816                     record = new Array();
3817                     record['xmlDoc'] = data;
3818                     record['offset'] = context.currRecOffset;
3819                     callback(record, args, context.windowid);
3820                 //pz2 record
3821                 } else if ( recordNode = 
3822                     data.getElementsByTagName("record")[0] ) {
3823                     // if stylesheet was fetched do not parse the response
3824                     if ( context.xslDoc ) {
3825                         record = new Array();
3826                         record['xmlDoc'] = data;
3827                         record['xslDoc'] = context.xslDoc;
3828                         record['recid'] = 
3829                             recordNode.getElementsByTagName("recid")[0]
3830                                 .firstChild.nodeValue;
3831                     //parse record
3832                     } else {
3833                         record = Element_parseChildNodes(recordNode);
3834                     }    
3835                     var activeClients = 
3836                        Number( data.getElementsByTagName("activeclients")[0]
3837                                 .childNodes[0].nodeValue );
3838                     context.activeClients = activeClients; 
3839                     context.recordCounter++;
3840                     var delay = context.recordTime + context.recordCounter * context.dumpFactor;
3841                     if ( activeClients > 0 )
3842                         context.recordTimer = 
3843                            setTimeout ( 
3844                                function() {
3845                                   context.record(id, offset, syntax, handler);
3846                                   },
3847                                   delay
3848                                );                                    
3849                     callback(record, args, context.windowid);
3850                 }
3851                 else
3852                     context.throwError('Record failed. Malformed WS resonse.',
3853                                         115);
3854             }
3855         );
3856     },
3857
3858     termlist: function()
3859     {
3860         if( !this.searchStatusOK && this.useSessions )
3861             throw new Error(
3862             'Pz2.js: termlist command has to be preceded with a search command.'
3863             );
3864
3865         // if called explicitly takes precedence
3866         clearTimeout(this.termTimer);
3867         
3868         var context = this;
3869         var request = new pzHttpRequest(this.pz2String, this.errorHandler);
3870         request.safeGet(
3871             { 
3872                 "command": "termlist", 
3873                 "session": this.sessionID, 
3874                 "name": this.termKeys,
3875                 "windowid" : this.windowid, 
3876                 "version" : this.version
3877         
3878             },
3879             function(data) {
3880                 if ( data.getElementsByTagName("termlist") ) {
3881                     var activeClients = 
3882                         Number( data.getElementsByTagName("activeclients")[0]
3883                                     .childNodes[0].nodeValue );
3884                     context.activeClients = activeClients;
3885                     var termList = { "activeclients":  activeClients };
3886                     var termLists = data.getElementsByTagName("list");
3887                     //for each termlist
3888                     for (i = 0; i < termLists.length; i++) {
3889                         var listName = termLists[i].getAttribute('name');
3890                         termList[listName] = new Array();
3891                         var terms = termLists[i].getElementsByTagName('term');
3892                         //for each term in the list
3893                         for (j = 0; j < terms.length; j++) { 
3894                             var term = {
3895                                 "name": 
3896                                     (terms[j].getElementsByTagName("name")[0]
3897                                         .childNodes.length 
3898                                     ? terms[j].getElementsByTagName("name")[0]
3899                                         .childNodes[0].nodeValue
3900                                     : 'ERROR'),
3901                                 "freq": 
3902                                     terms[j]
3903                                     .getElementsByTagName("frequency")[0]
3904                                     .childNodes[0].nodeValue || 'ERROR'
3905                             };
3906
3907                             // Only for xtargets: id, records, filtered
3908                             var termIdNode = 
3909                                 terms[j].getElementsByTagName("id");
3910                             if(terms[j].getElementsByTagName("id").length)
3911                                 term["id"] = 
3912                                     termIdNode[0].childNodes[0].nodeValue;
3913                             termList[listName][j] = term;
3914
3915                             var recordsNode  = terms[j].getElementsByTagName("records");
3916                             if (recordsNode && recordsNode.length)
3917                                 term["records"] = recordsNode[0].childNodes[0].nodeValue;
3918                               
3919                             var filteredNode  = terms[j].getElementsByTagName("filtered");
3920                             if (filteredNode && filteredNode.length)
3921                                 term["filtered"] = filteredNode[0].childNodes[0].nodeValue;
3922                               
3923                         }
3924                     }
3925
3926                     context.termCounter++;
3927                     var delay = context.termTime 
3928                         + context.termCounter * context.dumpFactor;
3929                     if ( activeClients > 0 )
3930                         context.termTimer = 
3931                             setTimeout(
3932                                 function () {
3933                                     context.termlist();
3934                                 }, 
3935                                 delay
3936                             );
3937                    
3938                     context.termlistCallback(termList, context.windowid);
3939                 }
3940                 else
3941                     context.throwError('Termlist failed. Malformed WS resonse.',
3942                                         116);
3943             }
3944         );
3945
3946     },
3947     bytarget: function()
3948     {
3949         if( !this.initStatusOK && this.useSessions )
3950             throw new Error(
3951             'Pz2.js: bytarget command has to be preceded with a search command.'
3952             );
3953         
3954         // no need to continue
3955         if( !this.searchStatusOK )
3956             return;
3957
3958         // if called explicitly takes precedence
3959         clearTimeout(this.bytargetTimer);
3960         
3961         var context = this;
3962         var request = new pzHttpRequest(this.pz2String, this.errorHandler);
3963         request.safeGet(
3964             { 
3965                 "command": "bytarget", 
3966                 "session": this.sessionID, 
3967                 "block": 1,
3968                 "windowid" : this.windowid,
3969                 "version" : this.version
3970             },
3971             function(data) {
3972                 if ( data.getElementsByTagName("status")[0]
3973                         .childNodes[0].nodeValue == "OK" ) {
3974                     var targetNodes = data.getElementsByTagName("target");
3975                     var bytarget = new Array();
3976                     for ( i = 0; i < targetNodes.length; i++) {
3977                         bytarget[i] = new Array();
3978                         for( j = 0; j < targetNodes[i].childNodes.length; j++ ) {
3979                             if ( targetNodes[i].childNodes[j].nodeType 
3980                                 == Node.ELEMENT_NODE ) {
3981                                 var nodeName = 
3982                                     targetNodes[i].childNodes[j].nodeName;
3983                                 if (targetNodes[i].childNodes[j].firstChild != null) 
3984                                 {
3985                                     var nodeText = targetNodes[i].childNodes[j]
3986                                         .firstChild.nodeValue;
3987                                     bytarget[i][nodeName] = nodeText;
3988                                 }
3989                                 else { 
3990                                     bytarget[i][nodeName] = "";  
3991                                 }
3992
3993
3994                             }
3995                         }
3996                         if (bytarget[i]["state"]=="Client_Disconnected") {
3997                           bytarget[i]["hits"] = "Error";
3998                         } else if (bytarget[i]["state"]=="Client_Error") {
3999                           bytarget[i]["hits"] = "Error";                          
4000                         } else if (bytarget[i]["state"]=="Client_Working") {
4001                           bytarget[i]["hits"] = "...";
4002                         }
4003                         var targetsSuggestions = targetNodes[i].getElementsByTagName("suggestions");
4004                         if (targetsSuggestions != undefined && targetsSuggestions.length>0) {
4005                           var suggestions = targetsSuggestions[0];
4006                           bytarget[i]["suggestions"] = Element_parseChildNodes(suggestions);
4007                         }
4008                     }
4009                     
4010                     context.bytargetCounter++;
4011                     var delay = context.bytargetTime 
4012                         + context.bytargetCounter * context.dumpFactor;
4013                     if ( context.activeClients > 0 )
4014                         context.bytargetTimer = 
4015                             setTimeout(
4016                                 function () {
4017                                     context.bytarget();
4018                                 }, 
4019                                 delay
4020                             );
4021
4022                     context.bytargetCallback(bytarget, context.windowid);
4023                 }
4024                 else
4025                     context.throwError('Bytarget failed. Malformed WS resonse.',
4026                                         117);
4027             }
4028         );
4029     },
4030     
4031     // just for testing, probably shouldn't be here
4032     showNext: function(page)
4033     {
4034         var step = page || 1;
4035         this.show( ( step * this.currentNum ) + this.currentStart );     
4036     },
4037
4038     showPrev: function(page)
4039     {
4040         if (this.currentStart == 0 )
4041             return false;
4042         var step = page || 1;
4043         var newStart = this.currentStart - (step * this.currentNum );
4044         this.show( newStart > 0 ? newStart : 0 );
4045     },
4046
4047     showPage: function(pageNum)
4048     {
4049         //var page = pageNum || 1;
4050         this.show(pageNum * this.currentNum);
4051     }
4052 };
4053
4054 /*
4055 ********************************************************************************
4056 ** AJAX HELPER CLASS ***********************************************************
4057 ********************************************************************************
4058 */
4059 var pzHttpRequest = function (url, errorHandler, cookieDomain, windowId) {
4060         this.maxUrlLength = 2048;
4061         this.request = null;
4062         this.url = url;
4063         this.errorHandler = errorHandler || null;
4064         this.async = true;
4065         this.requestHeaders = {};
4066         this.isXDR = false;
4067         this.domainRegex = /https?:\/\/([^:/]+).*/;
4068         this.cookieDomain = cookieDomain || null;
4069         this.windowId = windowId || window.name;
4070
4071         var xhr = new XMLHttpRequest();
4072         var domain = this._getDomainFromUrl(url);
4073         if ("withCredentials" in xhr) {
4074           // XHR for Chrome/Firefox/Opera/Safari.
4075         } else if (domain && this._isCrossDomain(domain) &&
4076             typeof XDomainRequest != "undefined") {
4077           // use XDR (IE7/8) when no other way
4078           xhr = new XDomainRequest();
4079           this.isXDR = true;
4080         } else {
4081           // CORS not supported.
4082         }
4083         this.request = xhr;
4084 };
4085
4086
4087 pzHttpRequest.prototype = 
4088 {
4089     safeGet: function ( params, callback )
4090     {
4091         var encodedParams =  this.encodeParams(params);
4092         var url = this._urlAppendParams(encodedParams);
4093         if (url.length >= this.maxUrlLength) {
4094             this.requestHeaders["Content-Type"]
4095                 = "application/x-www-form-urlencoded";
4096             this._send( 'POST', this.url, encodedParams, callback );
4097         } else {
4098             this._send( 'GET', url, '', callback );
4099         }
4100     },
4101
4102     get: function ( params, callback ) 
4103     {
4104         this._send( 'GET', this._urlAppendParams(this.encodeParams(params)), 
4105             '', callback );
4106     },
4107
4108     post: function ( params, data, callback )
4109     {
4110         this._send( 'POST', this._urlAppendParams(this.encodeParams(params)), 
4111             data, callback );
4112     },
4113
4114     load: function ()
4115     {
4116         this.async = false;
4117         this.request.open( 'GET', this.url, this.async );
4118         this.request.send('');
4119         if ( this.request.status == 200 )
4120             return this.request.responseXML;
4121     },
4122
4123     encodeParams: function (params)
4124     {
4125         var sep = "";
4126         var encoded = "";
4127         for (var key in params) {
4128             if (params[key] != null) {
4129                 encoded += sep + key + '=' + encodeURIComponent(params[key]);
4130                 sep = '&';
4131             }
4132         }
4133         return encoded;
4134     },
4135
4136     _getDomainFromUrl: function (url)
4137     {
4138       if (this.cookieDomain) return this.cookieDomain; //explicit cookie domain
4139       var m = this.domainRegex.exec(url);
4140       return (m && m.length > 1) ? m[1] : null;
4141     },
4142
4143     _strEndsWith: function (str, suffix) 
4144     {
4145       return str.indexOf(suffix, str.length - suffix.length) !== -1;
4146     },
4147
4148     _isCrossDomain: function (domain)
4149     {
4150       if (this.cookieDomain) return true; //assume xdomain is cookie domain set
4151       return !this._strEndsWith(domain, document.domain); 
4152     },
4153
4154     getCookie: function (sKey) {
4155       return decodeURI(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" 
4156         + encodeURI(sKey).replace(/[\-\.\+\*]/g, "\\$&") 
4157         + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1")) || null;
4158     },
4159
4160     setCookie: function (sKey, sValue, vEnd, sPath, sDomain, bSecure) {
4161       if (!sKey || /^(?:expires|max\-age|path|domain|secure)$/i.test(sKey)) { 
4162         return false; 
4163       }
4164       var sExpires = "";
4165       if (vEnd) {
4166         switch (vEnd.constructor) {
4167           case Number:
4168             sExpires = vEnd === Infinity 
4169               ? "; expires=Fri, 31 Dec 9999 23:59:59 GMT" 
4170               : "; max-age=" + vEnd;
4171             break;
4172           case String:
4173             sExpires = "; expires=" + vEnd;
4174             break;
4175           case Date:
4176             sExpires = "; expires=" + vEnd.toGMTString();
4177             break;
4178         }
4179       }
4180       document.cookie = encodeURI(sKey) + "=" + encodeURI(sValue) 
4181         + sExpires 
4182         + (sDomain ? "; domain=" + sDomain : "") 
4183         + (sPath ? "; path=" + sPath : "") 
4184         + (bSecure ? "; secure" : "");
4185       return true;
4186     },
4187     
4188     _send: function ( type, url, data, callback)
4189     {
4190         var context = this;
4191         this.callback = callback;
4192         this.async = true;
4193         //we never do withCredentials, so if it's CORS and we have
4194         //session cookie, resend it
4195         var domain = this._getDomainFromUrl(url);
4196         if (domain && this._isCrossDomain(domain) &&
4197             this.getCookie(domain+":"+this.windowId+":SESSID")) {
4198           //rewrite the URL
4199           var sessparam = ';jsessionid=' + this.getCookie(domain+":"+this.windowId+":SESSID");
4200           var q = url.indexOf('?');
4201           if (q == -1) {
4202             url += sessparam;            
4203           } else {
4204             url = url.substring(0, q) + sessparam + url.substring(q);
4205           }
4206         }
4207         this.request.open( type, url, this.async );
4208         if (!this.isXDR) {
4209           //setting headers is only allowed with XHR
4210           for (var key in this.requestHeaders)
4211             this.request.setRequestHeader(key, this.requestHeaders[key]);
4212         }
4213         if (this.isXDR) {
4214           this.request.onload = function () {
4215             //fake XHR props
4216             context.request.status = 200;
4217             context.request.readyState = 4;
4218             //handle
4219             context._handleResponse(url);
4220           }
4221           this.request.onerror = function () {
4222             //fake XHR props
4223             context.request.status = 417; //not really, but what can we do
4224             context.request.readyState = 4;
4225             //handle
4226             context._handleResponse(url);
4227           }
4228         } else {
4229           this.request.onreadystatechange = function () {
4230             context._handleResponse(url); /// url used ONLY for error reporting
4231           }
4232         }
4233         this.request.send(data);
4234     },
4235
4236     _urlAppendParams: function (encodedParams)
4237     {
4238         if (encodedParams)
4239             return this.url + "?" + encodedParams;
4240         else
4241             return this.url;
4242     },
4243
4244     _handleResponse: function (requestUrl)
4245     {
4246         if ( this.request.readyState == 4 ) { 
4247             // pick up appplication errors first
4248             var errNode = null;
4249             // xdomainreq does not have responseXML
4250             if (this.isXDR) {
4251               if (this.request.contentType.match(/\/xml/)){                
4252                 var dom = new ActiveXObject('Microsoft.XMLDOM');
4253                 dom.async = false;                
4254                 dom.loadXML(this.request.responseText);
4255                 this.request.responseXML = dom;
4256               } else {
4257                 this.request.responseXML = null;
4258               }
4259             }
4260             if (this.request.responseXML &&
4261                 (errNode = this.request.responseXML.documentElement)
4262                 && errNode.nodeName == 'error') {
4263                 var errMsg = errNode.getAttribute("msg");
4264                 var errCode = errNode.getAttribute("code");
4265                 var errAddInfo = '';
4266                 if (errNode.childNodes.length)
4267                     errAddInfo = ': ' + errNode.childNodes[0].nodeValue;
4268                            
4269                 var err = new Error(errMsg + errAddInfo);
4270                 err.code = errCode;
4271             
4272                 if (this.errorHandler) {
4273                     this.errorHandler(err);
4274                 }
4275                 else {
4276                     throw err;
4277                 }
4278             } 
4279             else if (this.request.status == 200 && 
4280                      this.request.responseXML === null) {
4281               if (this.request.responseText !== null) {
4282                 //assume JSON
4283                         var json = null; 
4284                         var text = this.request.responseText;
4285                         if (typeof window.JSON == "undefined") {
4286                           json = eval("(" + text + ")");
4287                 } else { 
4288                           try {
4289                             json = JSON.parse(text);
4290                           } catch (e) {
4291                   }
4292                         } 
4293                         this.callback(json, "json");
4294               } else {
4295                 var err = new Error("XML/Text response is empty but no error " +
4296                                     "for " + requestUrl);
4297                 err.code = -1;
4298                 if (this.errorHandler) {
4299                     this.errorHandler(err);
4300                 } else {
4301                     throw err;
4302                 }
4303               }
4304             } else if (this.request.status == 200) {
4305                 //set cookie manually only if cross-domain
4306                 var domain = this._getDomainFromUrl(requestUrl);
4307                 if (domain && this._isCrossDomain(domain)) {
4308                   var jsessionId = this.request.responseXML
4309                     .documentElement.getAttribute('jsessionId');
4310                   if (jsessionId)                  
4311                     this.setCookie(domain+":"+this.windowId+":SESSID", jsessionId);
4312                 }
4313                 this.callback(this.request.responseXML);
4314             } else {
4315                 var err = new Error("HTTP response not OK: " 
4316                             + this.request.status + " - " 
4317                             + this.request.statusText );
4318                 err.code = '00' + this.request.status;        
4319                 if (this.errorHandler) {
4320                     this.errorHandler(err);
4321                 }
4322                 else {
4323                     throw err;
4324                 }
4325             }
4326         }
4327     }
4328 };
4329
4330 /*
4331 ********************************************************************************
4332 ** XML HELPER FUNCTIONS ********************************************************
4333 ********************************************************************************
4334 */
4335
4336 // DOMDocument
4337
4338 if ( window.ActiveXObject) {
4339     var DOMDoc = document;
4340 } else {
4341     var DOMDoc = Document.prototype;
4342 }
4343
4344 DOMDoc.newXmlDoc = function ( root )
4345 {
4346     var doc;
4347
4348     if (document.implementation && document.implementation.createDocument) {
4349         doc = document.implementation.createDocument('', root, null);
4350     } else if ( window.ActiveXObject ) {
4351         doc = new ActiveXObject("MSXML2.DOMDocument");
4352         doc.loadXML('<' + root + '/>');
4353     } else {
4354         throw new Error ('No XML support in this browser');
4355     }
4356
4357     return doc;
4358 }
4359
4360    
4361 DOMDoc.parseXmlFromString = function ( xmlString ) 
4362 {
4363     var doc;
4364
4365     if ( window.DOMParser ) {
4366         var parser = new DOMParser();
4367         doc = parser.parseFromString( xmlString, "text/xml");
4368     } else if ( window.ActiveXObject ) {
4369         doc = new ActiveXObject("MSXML2.DOMDocument");
4370         doc.loadXML( xmlString );
4371     } else {
4372         throw new Error ("No XML parsing support in this browser.");
4373     }
4374
4375     return doc;
4376 }
4377
4378 DOMDoc.transformToDoc = function (xmlDoc, xslDoc)
4379 {
4380     if ( window.XSLTProcessor ) {
4381         var proc = new XSLTProcessor();
4382         proc.importStylesheet( xslDoc );
4383         return proc.transformToDocument(xmlDoc);
4384     } else if ( window.ActiveXObject ) {
4385         return document.parseXmlFromString(xmlDoc.transformNode(xslDoc));
4386     } else {
4387         alert( 'Unable to perform XSLT transformation in this browser' );
4388     }
4389 }
4390  
4391 // DOMElement
4392
4393 Element_removeFromDoc = function (DOM_Element)
4394 {
4395     DOM_Element.parentNode.removeChild(DOM_Element);
4396 }
4397
4398 Element_emptyChildren = function (DOM_Element)
4399 {
4400     while( DOM_Element.firstChild ) {
4401         DOM_Element.removeChild( DOM_Element.firstChild )
4402     }
4403 }
4404
4405 Element_appendTransformResult = function ( DOM_Element, xmlDoc, xslDoc )
4406 {
4407     if ( window.XSLTProcessor ) {
4408         var proc = new XSLTProcessor();
4409         proc.importStylesheet( xslDoc );
4410         var docFrag = false;
4411         docFrag = proc.transformToFragment( xmlDoc, DOM_Element.ownerDocument );
4412         DOM_Element.appendChild(docFrag);
4413     } else if ( window.ActiveXObject ) {
4414         DOM_Element.innerHTML = xmlDoc.transformNode( xslDoc );
4415     } else {
4416         alert( 'Unable to perform XSLT transformation in this browser' );
4417     }
4418 }
4419  
4420 Element_appendTextNode = function (DOM_Element, tagName, textContent )
4421 {
4422     var node = DOM_Element.ownerDocument.createElement(tagName);
4423     var text = DOM_Element.ownerDocument.createTextNode(textContent);
4424
4425     DOM_Element.appendChild(node);
4426     node.appendChild(text);
4427
4428     return node;
4429 }
4430
4431 Element_setTextContent = function ( DOM_Element, textContent )
4432 {
4433     if (typeof DOM_Element.textContent !== "undefined") {
4434         DOM_Element.textContent = textContent;
4435     } else if (typeof DOM_Element.innerText !== "undefined" ) {
4436         DOM_Element.innerText = textContent;
4437     } else {
4438         throw new Error("Cannot set text content of the node, no such method.");
4439     }
4440 }
4441
4442 Element_getTextContent = function (DOM_Element)
4443 {
4444     if ( typeof DOM_Element.textContent != 'undefined' ) {
4445         return DOM_Element.textContent;
4446     } else if (typeof DOM_Element.text != 'undefined') {
4447         return DOM_Element.text;
4448     } else {
4449         throw new Error("Cannot get text content of the node, no such method.");
4450     }
4451 }
4452
4453 Element_parseChildNodes = function (node)
4454 {
4455     var parsed = {};
4456     var hasChildElems = false;
4457     var textContent = '';
4458
4459     if (node.hasChildNodes()) {
4460         var children = node.childNodes;
4461         for (var i = 0; i < children.length; i++) {
4462             var child = children[i];
4463             switch (child.nodeType) {
4464               case Node.ELEMENT_NODE:
4465                 hasChildElems = true;
4466                 var nodeName = child.nodeName; 
4467                 if (!(nodeName in parsed))
4468                     parsed[nodeName] = [];
4469                 parsed[nodeName].push(Element_parseChildNodes(child));
4470                 break;
4471               case Node.TEXT_NODE:
4472                 textContent += child.nodeValue;
4473                 break;
4474               case Node.CDATA_SECTION_NODE:
4475                 textContent += child.nodeValue;
4476                 break;
4477             }
4478         }
4479     }
4480
4481     var attrs = node.attributes;
4482     for (var i = 0; i < attrs.length; i++) {
4483         hasChildElems = true;
4484         var attrName = '@' + attrs[i].nodeName;
4485         var attrValue = attrs[i].nodeValue;
4486         parsed[attrName] = attrValue;
4487     }
4488
4489     // if no nested elements/attrs set value to text
4490     if (hasChildElems)
4491       parsed['#text'] = textContent;
4492     else
4493       parsed = textContent;
4494     
4495     return parsed;
4496 }
4497
4498 /* do not remove trailing bracket */
4499 }
4500 // Handlebars helpers
4501
4502 Handlebars.registerHelper('mkws-json', function(obj) {
4503   return mkws.$.toJSON(obj);
4504 });
4505
4506
4507 // This is intended to handle paragraphs from Wikipedia, hence the
4508 // rather hacky code to remove numbered references.
4509 //
4510 Handlebars.registerHelper('mkws-paragraphs', function(obj, nPara, nSent) {
4511   var acc = [];
4512
4513   // For some reason, Handlebars provides the value
4514   // {"hash":{},"data":{}} for parameters that are not provided. So we
4515   // have to be prepared for actual numbers, explicitly undefined
4516   // values and this dumb magic value.
4517   if (obj && (nPara === undefined || nPara.hasOwnProperty('hash') || nPara == 0 || nPara > obj.length)) {
4518     nPara = obj.length;
4519   }
4520   if (nSent === undefined || nSent.hasOwnProperty('hash') || nSent == 0) {
4521     nSent = Infinity;
4522   }
4523
4524   for (var i = 0; i < nPara; i++) {
4525     // Remove numbered references such as "[1,3,4]" from text
4526     var text = obj[i].replace(/\[[0-9,]+\]/g, '');
4527     // Next line from http://stackoverflow.com/questions/18914629/split-string-into-sentences-in-javascript
4528     var sentences = text.replace(/([.?!])\s*(?=[A-Z])/g, "$1|").split("|");
4529     if (sentences.length > nSent)
4530       sentences.length = nSent;
4531
4532     acc.push('<p>', sentences.join(' '), '</p>');
4533     nSent -= sentences.length;
4534     if (nSent == 0)
4535       break;
4536   }
4537
4538   return acc.join('');
4539 });
4540
4541
4542 Handlebars.registerHelper('mkws-translate', function(s) {
4543   return mkws.M(s);
4544 });
4545
4546
4547 // We need {{mkws-attr '@name'}} because Handlebars can't parse {{@name}}
4548 Handlebars.registerHelper('mkws-attr', function(attrName) {
4549   return this[attrName];
4550 });
4551
4552
4553 /*
4554  * Use as follows: {{#mkws-if-any NAME1 having="NAME2"}}
4555  * Applicable when NAME1 is the name of an array
4556  * The guarded code runs only if at least one element of the NAME1
4557  * array has a subelement called NAME2.
4558  */
4559 Handlebars.registerHelper('mkws-if-any', function(items, options) {
4560   var having = options.hash.having;
4561   for (var i in items) {
4562     var item = items[i]
4563     if (!having || item[having]) {
4564       return options.fn(this);
4565     }
4566   }
4567   return "";
4568 });
4569
4570
4571 Handlebars.registerHelper('mkws-first', function(items, options) {
4572   var having = options.hash.having;
4573   for (var i in items) {
4574     var item = items[i]
4575     if (!having || item[having]) {
4576       return options.fn(item);
4577     }
4578   }
4579   return "";
4580 });
4581
4582
4583 Handlebars.registerHelper('mkws-commaList', function(items, options) {
4584   var out = "";
4585
4586   for (var i in items) {
4587     if (i > 0) out += ", ";
4588     out += options.fn(items[i])
4589   }
4590
4591   return out;
4592 });
4593
4594
4595 Handlebars.registerHelper('mkws-index1', function(obj) {
4596   return obj.data.index + 1;
4597 });
4598
4599 Handlebars.registerHelper('mkws-repeat', function(count, options) {
4600   var out = "";
4601   for (var i = 0; i < count; i++) {
4602     out += options.fn(this);
4603   }
4604   return out;
4605 });
4606 /*! MKWS, the MasterKey Widget Set.
4607  *  Copyright (C) 2013-2014 Index Data
4608  *  See the file LICENSE for details
4609  */
4610
4611 "use strict"; // HTML5: disable for log_level >= 2
4612
4613
4614 // Set up global mkws object. Contains truly global state such as SP
4615 // authentication, and a hash of team objects, indexed by team-name.
4616 //
4617 // We set it as a property of window to make the global explicit as
4618 // some things complain about an implicit global.
4619 window.mkws = {
4620   $: $, // Our own local copy of the jQuery object
4621   authenticated: false,
4622   authenticating: false,
4623   active: false,
4624   log_level: 1, // Will be overridden from mkws.config, but
4625                 // initial value allows jQuery popup to use logging.
4626   teams: {},
4627   widgetType2function: {},
4628   defaultTemplates: {},
4629
4630   locale_lang: {
4631     "de": {
4632       "Authors": "Autoren",
4633       "Subjects": "Schlagw&ouml;rter",
4634       "Sources": "Daten und Quellen",
4635       "source": "datenquelle",
4636       "Facets": "Termlisten",
4637       "Next": "Weiter",
4638       "Prev": "Zur&uuml;ck",
4639       "Search": "Suche",
4640       "Sort by": "Sortieren nach",
4641       "and show": "und zeige",
4642       "per page": "pro Seite",
4643       "Displaying": "Zeige",
4644       "to": "von",
4645       "of": "aus",
4646       "found": "gefunden",
4647       "Title": "Titel",
4648       "Author": "Autor",
4649       "author": "autor",
4650       "Date": "Datum",
4651       "Subject": "Schlagwort",
4652       "subject": "schlagwort",
4653       "Location": "Ort",
4654       "Records": "Datens&auml;tze",
4655       "Targets": "Datenbanken",
4656
4657       "dummy": "dummy"
4658     },
4659
4660     "da": {
4661       "Authors": "Forfattere",
4662       "Subjects": "Emner",
4663       "Sources": "Kilder",
4664       "source": "kilder",
4665       "Facets": "Termlists",
4666       "Next": "N&aelig;ste",
4667       "Prev": "Forrige",
4668       "Search": "S&oslash;g",
4669       "Sort by": "Sorter efter",
4670       "and show": "og vis",
4671       "per page": "per side",
4672       "Displaying": "Viser",
4673       "to": "til",
4674       "of": "ud af",
4675       "found": "fandt",
4676       "Title": "Title",
4677       "Author": "Forfatter",
4678       "author": "forfatter",
4679       "Date": "Dato",
4680       "Subject": "Emneord",
4681       "subject": "emneord",
4682       "Location": "Lokation",
4683       "Records": "Poster",
4684       "Targets": "Baser",
4685
4686       "dummy": "dummy"
4687     }
4688   }
4689 };
4690
4691 // We may be using a separate copy
4692 if (typeof(mkws_jQuery) !== "undefined") {
4693   mkws.$ = mkws_jQuery;
4694 } else {
4695   mkws.$ = jQuery;
4696 }
4697
4698 mkws.log = function(string) {
4699   if (!mkws.log_level)
4700     return;
4701
4702   if (typeof console === "undefined" || typeof console.log === "undefined") { /* ARGH!!! old IE */
4703     return;
4704   }
4705
4706   // you need to disable use strict at the top of the file!!!
4707   if (mkws.log_level >= 3) {
4708     // Works in Chrome; not sure about elsewhere
4709     console.trace();
4710   } else if (mkws.log_level >= 2) {
4711     console.log(">>> called from function " + arguments.callee.caller.name + ' <<<');
4712   }
4713   console.log(string);
4714 };
4715
4716
4717 // Translation function.
4718 mkws.M = function(word) {
4719   var lang = mkws.config.lang;
4720
4721   if (!lang || !mkws.locale_lang[lang])
4722     return word;
4723
4724   return mkws.locale_lang[lang][word] || word;
4725 };
4726
4727
4728 // This function is taken from a StackOverflow answer
4729 // http://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript/901144#901144
4730 mkws.getParameterByName = function(name, url) {
4731   if (!url) url = location.search;
4732   name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
4733   var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
4734   results = regex.exec(url);
4735   return results == null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
4736 }
4737
4738
4739 mkws.registerWidgetType = function(name, fn) {
4740   if(mkws._old2new.hasOwnProperty(name)) {
4741       mkws.log("Warning: registerWidgetType old widget name: " + name + " => " + mkws._old2new[name]);
4742       name = mkws._old2new[name];
4743   }
4744
4745   mkws.widgetType2function[name] = fn;
4746   mkws.log("registered widget-type '" + name + "'");
4747 };
4748
4749 mkws.promotionFunction = function(name) {
4750   return mkws.widgetType2function[name];
4751 };
4752
4753
4754 mkws.setMkwsConfig = function(overrides) {
4755   // Set global log_level flag early so that mkws.log() works
4756   var tmp = overrides.log_level;
4757   if (typeof(tmp) !== 'undefined') mkws.log_level = tmp;
4758
4759   var config_default = {
4760     use_service_proxy: true,
4761     pazpar2_url: undefined,
4762     pp2_hostname: "sp-mkws.indexdata.com",
4763     pp2_path: "service-proxy/",
4764     service_proxy_auth: undefined,
4765     sp_auth_path: undefined,
4766     sp_auth_query: "command=auth&action=perconfig",
4767     sp_auth_credentials: undefined,
4768     lang: "",
4769     sort_options: [["relevance"], ["title:1", "title"], ["date:0", "newest"], ["date:1", "oldest"]],
4770     perpage_options: [10, 20, 30, 50],
4771     sort_default: "relevance",
4772     perpage_default: 20,
4773     show_lang: true,    /* show/hide language menu */
4774     show_sort: true,    /* show/hide sort menu */
4775     show_perpage: true, /* show/hide perpage menu */
4776     show_switch: true,  /* show/hide switch menu */
4777     lang_options: [],   /* display languages links for given languages, [] for all */
4778     facets: ["xtargets", "subject", "author"], /* display facets, in this order, [] for none */
4779     responsive_design_width: undefined, /* a page with less pixel width considered as narrow */
4780     log_level: 1,     /* log level for development: 0..2 */
4781     template_vars: {}, /* values that may be exposed to templates */
4782
4783     dummy: "dummy"
4784   };
4785
4786   mkws.config = mkws.objectInheritingFrom(config_default);
4787   for (var k in overrides) {
4788     mkws.config[k] = overrides[k];
4789   }
4790 };
4791
4792
4793 // This code is from Douglas Crockford's article "Prototypal Inheritance in JavaScript"
4794 // http://javascript.crockford.com/prototypal.html
4795 // mkws.objectInheritingFrom behaves the same as Object.create,
4796 // but since the latter is not available in IE8 we can't use it.
4797 //
4798 mkws.objectInheritingFrom = function(o) {
4799   function F() {}
4800   F.prototype = o;
4801   return new F();
4802 }
4803
4804
4805 // The following functions are dispatchers for team methods that
4806 // are called from the UI using a team-name rather than implicit
4807 // context.
4808 mkws.switchView = function(tname, view) {
4809   mkws.teams[tname].switchView(view);
4810 };
4811
4812 mkws.showDetails = function(tname, prefixRecId) {
4813   mkws.teams[tname].showDetails(prefixRecId);
4814 };
4815
4816 mkws.limitTarget  = function(tname, id, name) {
4817   mkws.teams[tname].limitTarget(id, name);
4818 };
4819
4820 mkws.limitQuery  = function(tname, field, value) {
4821   mkws.teams[tname].limitQuery(field, value);
4822 };
4823
4824 mkws.limitCategory  = function(tname, id) {
4825   mkws.teams[tname].limitCategory(id);
4826 };
4827
4828 mkws.delimitTarget = function(tname, id) {
4829   mkws.teams[tname].delimitTarget(id);
4830 };
4831
4832 mkws.delimitQuery = function(tname, field, value) {
4833   mkws.teams[tname].delimitQuery(field, value);
4834 };
4835
4836 mkws.showPage = function(tname, pageNum) {
4837   mkws.teams[tname].showPage(pageNum);
4838 };
4839
4840 mkws.pagerPrev = function(tname) {
4841   mkws.teams[tname].pagerPrev();
4842 };
4843
4844 mkws.pagerNext = function(tname) {
4845   mkws.teams[tname].pagerNext();
4846 };
4847
4848
4849 mkws.pazpar2_url = function() {
4850   if (mkws.config.pazpar2_url) {
4851     mkws.log("using pre-baked pazpar2_url '" + mkws.config.pazpar2_url + "'");
4852     return mkws.config.pazpar2_url;
4853   } else {
4854     var s = document.location.protocol + "//" + mkws.config.pp2_hostname + "/" + mkws.config.pp2_path;
4855     mkws.log("generated pazpar2_url '" + s + "'");
4856     return s;
4857   }
4858 };
4859
4860
4861 // We put a session token in window.name, as it's the only place to
4862 // keep data that is preserved across reloads and within-site
4863 // navigation. pz2.js picks this up and uses it as part of the
4864 // cookie-name, to ensure we get a new session when we need one.
4865 //
4866 // We want to use different sessions for different windows/tabs (so
4867 // they don't receive each other's messages), different hosts and
4868 // different paths on a host (since in general these will
4869 // authenticate as different libraries). So the window name needs to
4870 // include the hostname and the path from the URL, plus the token.
4871 //
4872 var token;
4873 if (window.name) {
4874   token = window.name.replace(/.*\//, '');
4875   mkws.log("Reusing existing window token '" + token + "'");
4876 } else {
4877   // Incredible that the standard JavaScript runtime doesn't define a
4878   // unique windowId. Instead, we have to make one up. And since there's
4879   // no global area shared between windows, the best we can do for
4880   // ensuring uniqueness is generating a random ID and crossing our
4881   // fingers.
4882   //
4883   // Ten chars from 26 alpha-numerics = 36^10 = 3.65e15 combinations.
4884   // At one per second, it will take 116 million years to duplicate a token
4885   token = Math.random().toString(36).slice(2, 12);
4886   mkws.log("Generated new window token '" + token + "'");
4887 }
4888
4889 window.name = window.location.hostname + window.location.pathname + '/' + token;
4890 mkws.log("Using window.name '" + window.name + "'");
4891
4892
4893 // wrapper to provide local copy of the jQuery object.
4894 (function($) {
4895   var log = mkws.log;
4896   var _old2new = { // Maps old-style widget names to new-style
4897     'Authname': 'auth-name',
4898     'ConsoleBuilder': 'console-builder',
4899     'Coverart': 'cover-art',
4900     'GoogleImage': 'google-image',
4901     'MOTD': 'motd',
4902     'MOTDContainer': 'motd-container',
4903     'Perpage': 'per-page',
4904     'SearchForm': 'search-form',
4905     'ReferenceUniverse': 'reference-universe',
4906     'Termlists': 'facets'
4907   };
4908   // Annoyingly, there is no built-in way to invert a hash
4909   var _new2old = {};
4910   for (var key in _old2new) {
4911     if(_old2new.hasOwnProperty(key)) {
4912       _new2old[_old2new[key]] = key;
4913     }
4914   }
4915
4916   mkws._old2new = _old2new;
4917
4918   function handleNodeWithTeam(node, callback) {
4919     // First branch for DOM objects; second branch for jQuery objects
4920     var classes = node.className || node.attr('class');
4921     if (!classes) {
4922       // For some reason, if we try to proceed when classes is
4923       // undefined, we don't get an error message, but this
4924       // function and its callers, up several stack level,
4925       // silently return. What a crock.
4926       log("handleNodeWithTeam() called on node with no classes");
4927       return;
4928     }
4929     var list = classes.split(/\s+/)
4930     var teamName, type;
4931
4932     for (var i = 0; i < list.length; i++) {
4933       var cname = list[i];
4934       if (cname.match(/^mkws-team-/)) {
4935         // New-style teamnames of the form mkws-team-xyz
4936         teamName = cname.replace(/^mkws-team-/, '');
4937       } else if (cname.match(/^mkwsTeam_/)) {
4938         // Old-style teamnames of the form mkwsTeam_xyz
4939         teamName = cname.replace(/^mkwsTeam_/, '');
4940       } else if (cname.match(/^mkws-/)) {
4941         // New-style names of the from mkws-foo-bar
4942         type = cname.replace(/^mkws-/, '');
4943       } else if (cname.match(/^mkws/)) {
4944         // Old-style names of the form mkwsFooBar
4945         var tmp = cname.replace(/^mkws/, '');
4946         type = _old2new[tmp] || tmp.toLowerCase();
4947       }
4948     }
4949
4950     // Widgets without a team are on team "AUTO"
4951     if (!teamName) {
4952       teamName = "AUTO";
4953       // Autosearch widgets don't join team AUTO if there is already an
4954       // autosearch on the team or the team has otherwise gotten a query
4955       if (node.getAttribute("autosearch")) {
4956         if (mkws.autoHasAuto ||
4957             mkws.teams["AUTO"] && mkws.teams["AUTO"].config["query"]) {
4958           log("AUTO team already has a query, using unique team");
4959           teamName = "UNIQUE";
4960         }
4961         mkws.autoHasAuto = true;
4962       }
4963     }
4964
4965     // Widgets on team "UNIQUE" get a random team
4966     if (teamName === "UNIQUE") {
4967       teamName = Math.floor(Math.random() * 100000000).toString();
4968     }
4969
4970     callback.call(node, teamName, type);
4971   }
4972
4973
4974   function resizePage() {
4975     var threshhold = mkws.config.responsive_design_width;
4976     var width = $(window).width();
4977     var from, to, method;
4978
4979     if ((mkws.width === undefined || mkws.width > threshhold) &&
4980         width <= threshhold) {
4981       from = "wide"; to = "narrow"; method = "hide";
4982     } else if ((mkws.width === undefined || mkws.width <= threshhold) &&
4983                width > threshhold) {
4984       from = "narrow"; to = "wide"; method = "show";
4985     }
4986     mkws.width = width;
4987
4988     if (from) {
4989       log("changing from " + from + " to " + to + ": " + width);
4990       for (var tname in mkws.teams) {
4991         var team = mkws.teams[tname];
4992         team.visitWidgets(function(t, w) {
4993           var w1 = team.widget(t + "-container-" + from);
4994           var w2 = team.widget(t + "-container-" + to);
4995           if (w1) {
4996             w1.node.hide();
4997           }
4998           if (w2) {
4999             w2.node.show();
5000             w.node.appendTo(w2.node);
5001           }
5002         });
5003         team.queue("resize-" + to).publish();
5004       }
5005     }
5006   };
5007
5008
5009   /*
5010    * Run service-proxy authentication in background (after page load).
5011    * The username/password is configured in the apache config file
5012    * for the site.
5013    */
5014   function authenticateSession(auth_url, auth_domain, pp2_url) {
5015     mkws.authenticating = true;
5016     log("service proxy authentication on URL: " + auth_url);
5017
5018     if (!auth_domain) {
5019       auth_domain = pp2_url.replace(/^(https?:)?\/\/(.*?)\/.*/, '$2');
5020       log("guessed auth_domain '" + auth_domain + "' from pp2_url '" + pp2_url + "'");
5021     }
5022
5023     var request = new pzHttpRequest(auth_url, function(err) {
5024       alert("HTTP call for authentication failed: " + err)
5025       return;
5026     }, auth_domain);
5027
5028     request.get(null, function(data) {
5029       mkws.authenticating = false;
5030       if (!$.isXMLDoc(data)) {
5031         alert("Service Proxy authentication response is not a valid XML document");
5032         return;
5033       }
5034       var status = $(data).find("status");
5035       if (status.text() != "OK") {
5036         var message = $(data).find("message");
5037         alert("Service Proxy authentication response: " + status.text() + " (" + message.text() + ")");
5038         return;
5039       }
5040
5041       log("service proxy authentication successful");
5042       mkws.authenticated = true;
5043       var authName = $(data).find("displayName").text();
5044       // You'd think there would be a better way to do this:
5045       var realm = $(data).find("realm:not(realmAttributes realm)").text();
5046       for (var teamName in mkws.teams) {
5047         mkws.teams[teamName].queue("authenticated").publish(authName, realm);
5048       }
5049
5050       runAutoSearches();
5051     });
5052   }
5053
5054
5055   function runAutoSearches() {
5056     log("running auto searches");
5057
5058     for (var teamName in mkws.teams) {
5059       mkws.teams[teamName].queue("ready").publish();
5060     }
5061   }
5062
5063
5064   function selectorForAllWidgets() {
5065     if (mkws.config && mkws.config.scan_all_nodes) {
5066       // This is the old version, which works by telling jQuery to
5067       // find every node that has a class beginning with "mkws". In
5068       // theory it should be slower than the class-based selector; but
5069       // instrumentation suprisingly shows this is consistently
5070       // faster. It also has the advantage that any widgets of
5071       // non-registered types are logged as warnings rather than
5072       // silently ignored.
5073       return '[class^="mkws"],[class*=" mkws"]';
5074     } else {
5075       // This is the new version, which works by looking up the
5076       // specific classes of all registered widget types and their
5077       // resize containers. Because all it requires jQuery to do is
5078       // some hash lookups in pre-built tables, it should be very
5079       // fast; but it silently ignores widgets of unregistered types.
5080       var s = "";
5081       for (var type in mkws.widgetType2function) {
5082         if (s) s += ',';
5083         s += '.mkws-' + type;
5084         s += ',.mkws-' + type + "-container-wide";
5085         s += ',.mkws-' + type + "-container-narrow";
5086         // Annoyingly, we also need to recognise old-style names
5087         var oldtype = _new2old[type] || type.charAt(0).toUpperCase() + type.slice(1);
5088         s += ',.mkws' + oldtype;
5089         s += ',.mkws' + oldtype + "-Container-wide";
5090         s += ',.mkws' + oldtype + "-Container-narrow";
5091       }
5092       return s;
5093     }
5094   }
5095
5096
5097   function makeWidgetsWithin(level, node) {
5098     if (node) var widgetNodes = node.find(selectorForAllWidgets());
5099     else widgetNodes = $(selectorForAllWidgets());
5100     // Return false if we parse no widgets
5101     if (widgetNodes.length < 1) return false;
5102     widgetNodes.each(function() {
5103       handleNodeWithTeam(this, function(tname, type) {
5104         var myTeam = mkws.teams[tname];
5105         if (!myTeam) {
5106           myTeam = mkws.teams[tname] = mkws.makeTeam($, tname);
5107         }
5108
5109         var oldHTML = this.innerHTML;
5110         var myWidget = mkws.makeWidget($, myTeam, type, this);
5111         myTeam.addWidget(myWidget);
5112         var newHTML = this.innerHTML;
5113         if (newHTML !== oldHTML) {
5114           myTeam.log("widget " + type + " HTML changed: reparsing");
5115           makeWidgetsWithin(level+1, $(this));
5116         }
5117       });
5118     });
5119     return true;
5120   }
5121
5122
5123   // The second "rootsel" parameter is passed to jQuery and is a DOM node
5124   // or a selector string you would like to constrain the search for widgets to.
5125   //
5126   // This function has no side effects if run again on an operating session,
5127   // even if the element/selector passed causes existing widgets to be reparsed: 
5128   //
5129   // (TODO: that last bit isn't true and we currently have to avoid reinitialising
5130   // widgets, MKWS-261)
5131   //
5132   // * configuration is not regenerated
5133   // * authentication is not performed again
5134   // * autosearches are not re-run
5135   mkws.init = function(message, rootsel) {
5136     var greet = "MKWS initialised";
5137     if (rootsel) greet += " (limited to " + rootsel + ")"
5138     if (message) greet += " :: " + message; 
5139     mkws.log(greet);
5140
5141     // MKWS is not active until init() has been run against an object with widget nodes.
5142     // We only set initial configuration when MKWS is first activated.
5143     if (!mkws.isActive) {
5144       var widgetSelector = selectorForAllWidgets();
5145       if ($(widgetSelector).length < 1) {
5146         mkws.log("no widgets found");
5147         return;
5148       }
5149
5150       // Initial configuration
5151       mkws.autoHasAuto = false;
5152       var saved_config;
5153       if (typeof mkws_config === 'undefined') {
5154         log("setting empty config");
5155         saved_config = {};
5156       } else {
5157         log("using config: " + $.toJSON(mkws_config));
5158         saved_config = mkws_config;
5159       }
5160       mkws.setMkwsConfig(saved_config);
5161
5162       for (var key in mkws.config) {
5163         if (mkws.config.hasOwnProperty(key)) {
5164           if (key.match(/^language_/)) {
5165             var lang = key.replace(/^language_/, "");
5166             // Copy custom languages into list
5167             mkws.locale_lang[lang] = mkws.config[key];
5168             log("added locally configured language '" + lang + "'");
5169           }
5170         }
5171       }
5172
5173       var lang = mkws.getParameterByName("lang") || mkws.config.lang;
5174       if (!lang || !mkws.locale_lang[lang]) {
5175         mkws.config.lang = ""
5176       } else {
5177         mkws.config.lang = lang;
5178       }
5179
5180       log("using language: " + (mkws.config.lang ? mkws.config.lang : "none"));
5181
5182       // protocol independent link for pazpar2: "//mkws/sp" -> "https://mkws/sp"
5183       if (mkws.pazpar2_url().match(/^\/\//)) {
5184         mkws.config.pazpar2_url = document.location.protocol + mkws.config.pazpar2_url;
5185         log("adjusted protocol independent link to " + mkws.pazpar2_url());
5186       }
5187
5188       if (mkws.config.responsive_design_width) {
5189         // Responsive web design - change layout on the fly based on
5190         // current screen width. Required for mobile devices.
5191         $(window).resize(resizePage);
5192         // initial check after page load
5193         $(document).ready(resizePage);
5194       }
5195     }
5196
5197     var then = $.now();
5198     // If we've made no widgets, return without starting an SP session
5199     // or marking MKWS active.
5200     if (makeWidgetsWithin(1, rootsel ? $(rootsel) : undefined) === false) {
5201       return false;
5202     }
5203     var now = $.now();
5204
5205     log("walking MKWS nodes took " + (now-then) + " ms");
5206     for (var tName in mkws.teams) {
5207       var myTeam = mkws.teams[tName]
5208       myTeam.makePz2();
5209       myTeam.log("made PZ2 object");
5210       /*
5211         myTeam.visitWidgets(function(t, w) {
5212           log("  has widget of type '" + t + "': " + w);
5213         });
5214       */
5215     }
5216
5217     function sp_auth_url(config) {
5218       if (config.service_proxy_auth) {
5219         mkws.log("using pre-baked sp_auth_url '" + config.service_proxy_auth + "'");
5220         return config.service_proxy_auth;
5221       } else {
5222         var s = '//';
5223         s += config.sp_auth_hostname ? config.sp_auth_hostname : config.pp2_hostname;
5224         s += '/';
5225         s += config.sp_auth_path ? config.sp_auth_path : config.pp2_path;
5226         var q = config.sp_auth_query;
5227         if (q) {
5228           s += '?' + q;
5229         }
5230         var c = config.sp_auth_credentials;
5231         if (c) {
5232           s += ('&username=' + c.substr(0, c.indexOf('/')) +
5233                 '&password=' + c.substr(c.indexOf('/')+1));
5234         }
5235         mkws.log("generated sp_auth_url '" + s + "'");
5236         return s;
5237       }
5238     }
5239
5240     if (mkws.config.use_service_proxy && !mkws.authenticated && !mkws.authenticating) {
5241       authenticateSession(sp_auth_url(mkws.config),
5242                           mkws.config.service_proxy_auth_domain,
5243                           mkws.pazpar2_url());
5244     } else if (!mkws.authenticating) {
5245       // raw pp2 or we have a session already open
5246       runAutoSearches();
5247     }
5248     
5249     mkws.isActive = true;
5250     return true;
5251   };
5252
5253   $(document).ready(function() {
5254     if (!window.mkws_noready && !mkws.authenticating && !mkws.active) {
5255        mkws.init();
5256     }
5257   });
5258
5259 })(mkws.$);
5260 // Factory function for team objects. As much as possible, this uses
5261 // only member variables (prefixed "m_") and inner functions with
5262 // private scope.
5263 //
5264 // Some functions are visible as member-functions to be called from
5265 // outside code -- specifically, from generated HTML. These functions
5266 // are that.switchView(), showDetails(), limitTarget(), limitQuery(),
5267 // limitCategory(), delimitTarget(), delimitQuery(), showPage(),
5268 // pagerPrev(), pagerNext().
5269 //
5270 // Before the team can be used for searching and related operations,
5271 // its pz2 object must be created by calling team.makePz2().
5272 //
5273 mkws.makeTeam = function($, teamName) {
5274   var that = {};
5275   var m_teamName = teamName;
5276   var m_submitted = false;
5277   var m_query; // initially undefined
5278   var m_sortOrder; // will be set below
5279   var m_perpage; // will be set below
5280   var m_filterSet = filterSet(that);
5281   var m_totalRecordCount = 0;
5282   var m_currentPage = 1;
5283   var m_currentRecordId = '';
5284   var m_currentRecordData = null;
5285   var m_logTime = {
5286     // Timestamps for logging
5287     "start": $.now(),
5288     "last": $.now()
5289   };
5290   var m_paz; // will be initialised below
5291   var m_templateText = {}; // widgets can register templates to be compiled
5292   var m_template = {}; // compiled templates, from any source
5293   var m_widgets = {}; // Maps widget-type to array of widget objects
5294   var m_gotRecords = false;
5295   
5296   var config = mkws.objectInheritingFrom(mkws.config);
5297   that.config = config;
5298
5299   that.toString = function() { return '[Team ' + teamName + ']'; };
5300
5301   // Accessor methods for individual widgets: readers
5302   that.name = function() { return m_teamName; };
5303   that.submitted = function() { return m_submitted; };
5304   that.sortOrder = function() { return m_sortOrder; };
5305   that.perpage = function() { return m_perpage; };
5306   that.query = function() { return m_query; };
5307   that.totalRecordCount = function() { return m_totalRecordCount; };
5308   that.currentPage = function() { return m_currentPage; };
5309   that.currentRecordId = function() { return m_currentRecordId; };
5310   that.currentRecordData = function() { return m_currentRecordData; };
5311   that.filters = function() { return m_filterSet; };
5312   that.gotRecords = function() { return m_gotRecords; };
5313
5314   // Accessor methods for individual widgets: writers
5315   that.set_sortOrder = function(val) { m_sortOrder = val };
5316   that.set_perpage = function(val) { m_perpage = val };
5317
5318
5319   // The following PubSub code is modified from the jQuery manual:
5320   // http://api.jquery.com/jQuery.Callbacks/
5321   //
5322   // Use as:
5323   //    team.queue("eventName").subscribe(function(param1, param2 ...) { ... });
5324   //    team.queue("eventName").publish(arg1, arg2, ...);
5325   //
5326   var m_queues = {};
5327   function queue(id) {
5328     if (!m_queues[id]) {
5329       var callbacks = $.Callbacks();
5330       m_queues[id] = {
5331         publish: callbacks.fire,
5332         subscribe: callbacks.add,
5333         unsubscribe: callbacks.remove
5334       };
5335     }
5336     return m_queues[id];
5337   };
5338   that.queue = queue;
5339
5340
5341   function log(s) {
5342     var now = $.now();
5343     var timestamp = (((now - m_logTime.start)/1000).toFixed(3) + " (+" +
5344                      ((now - m_logTime.last)/1000).toFixed(3) + ") ");
5345     m_logTime.last = now;
5346     mkws.log(m_teamName + ": " + timestamp + s);
5347     that.queue("log").publish(m_teamName, timestamp, s);
5348   }
5349   that.log = log;
5350
5351
5352   log("making new widget team");
5353
5354   m_sortOrder = config.sort_default;
5355   m_perpage = config.perpage_default;
5356  
5357   // pz2.js event handlers:
5358   function onInit() {
5359     log("init");
5360     m_paz.stat();
5361     m_paz.bytarget();
5362   }
5363
5364   function onBytarget(data) {
5365     log("bytarget");
5366     queue("targets").publish(data);
5367   }
5368
5369   function onStat(data) {
5370     queue("stat").publish(data);
5371     var hitcount = parseInt(data.hits[0], 10);
5372     if (!m_gotRecords && hitcount > 0) {
5373       m_gotRecords = true;
5374       queue("firstrecords").publish(hitcount);
5375     }
5376     if (parseInt(data.activeclients[0], 10) === 0) {
5377       log("complete");
5378       queue("complete").publish(hitcount);
5379     }
5380   }
5381
5382   function onTerm(data) {
5383     log("term");
5384     queue("facets").publish(data);
5385   }
5386
5387   function onShow(data, teamName) {
5388     log("show");
5389     m_totalRecordCount = data.merged;
5390     log("found " + m_totalRecordCount + " records");
5391     queue("pager").publish(data);
5392     queue("records").publish(data);
5393   }
5394
5395   function onRecord(data, args, teamName) {
5396     log("record");
5397     // FIXME: record is async!!
5398     clearTimeout(m_paz.recordTimer);
5399     queue("record").publish(data);
5400     var detRecordDiv = findnode(recordDetailsId(data.recid[0]));
5401     if (detRecordDiv.length) {
5402       // in case on_show was faster to redraw element
5403       return;
5404     }
5405     m_currentRecordData = data;
5406     var recordDiv = findnode('.' + recordElementId(m_currentRecordData.recid[0]));
5407     var html = renderDetails(m_currentRecordData);
5408     $(recordDiv).append(html);
5409   }
5410
5411
5412   // create a parameters array and pass it to the pz2's constructor
5413   // then register the form submit event with the pz2.search function
5414   // autoInit is set to true on default
5415   that.makePz2 = function() {
5416     log("m_queues=" + $.toJSON(m_queues));
5417     var params = {
5418       "windowid": teamName,
5419       "pazpar2path": mkws.pazpar2_url(),
5420       "usesessions" : config.use_service_proxy ? false : true,
5421       "showtime": 500,            //each timer (show, stat, term, bytarget) can be specified this way
5422       "termlist": config.facets.join(',')
5423     };
5424
5425     params.oninit = onInit;
5426     if (m_queues.targets) {
5427       params.onbytarget = onBytarget;
5428       log("setting bytarget callback");
5429     }
5430     if (m_queues.stat) {
5431       params.onstat = onStat;
5432       log("setting stat callback");
5433     }
5434     if (m_queues.facets && config.facets.length) {
5435       params.onterm = onTerm;
5436       log("setting term callback");
5437     }
5438     if (m_queues.records) {
5439       log("setting show callback");
5440       params.onshow = onShow;
5441       // Record callback is subscribed from records callback
5442       log("setting record callback");
5443       params.onrecord = onRecord;
5444     }
5445
5446     m_paz = new pz2(params);
5447     log("created main pz2 object");
5448   }
5449
5450
5451   // Used by the Records widget and onRecord()
5452   function recordElementId(s) {
5453     return 'mkws-rec_' + s.replace(/[^a-z0-9]/ig, '_');
5454   }
5455   that.recordElementId = recordElementId;
5456
5457   // Used by onRecord(), showDetails() and renderDetails()
5458   function recordDetailsId(s) {
5459     return 'mkws-det_' + s.replace(/[^a-z0-9]/ig, '_');
5460   }
5461
5462
5463   that.targetFiltered = function(id) {
5464     return m_filterSet.targetFiltered(id);
5465   };
5466
5467
5468   that.limitTarget = function(id, name) {
5469     log("limitTarget(id=" + id + ", name=" + name + ")");
5470     m_filterSet.add(targetFilter(id, name));
5471     if (m_query) triggerSearch();
5472     return false;
5473   };
5474
5475
5476   that.limitQuery = function(field, value) {
5477     log("limitQuery(field=" + field + ", value=" + value + ")");
5478     m_filterSet.add(fieldFilter(field, value));
5479     if (m_query) triggerSearch();
5480     return false;
5481   };
5482
5483
5484   that.limitCategory = function(id) {
5485     log("limitCategory(id=" + id + ")");
5486     // Only one category filter at a time
5487     m_filterSet.removeMatching(function(f) { return f.type === 'category' });
5488     if (id !== '') m_filterSet.add(categoryFilter(id));
5489     if (m_query) triggerSearch();
5490     return false;
5491   };
5492
5493
5494   that.delimitTarget = function(id) {
5495     log("delimitTarget(id=" + id + ")");
5496     m_filterSet.removeMatching(function(f) { return f.type === 'target' });
5497     if (m_query) triggerSearch();
5498     return false;
5499   };
5500
5501
5502   that.delimitQuery = function(field, value) {
5503     log("delimitQuery(field=" + field + ", value=" + value + ")");
5504     m_filterSet.removeMatching(function(f) { return f.type == 'field' &&
5505                                              field == f.field && value == f.value });
5506     if (m_query) triggerSearch();
5507     return false;
5508   };
5509
5510
5511   that.showPage = function(pageNum) {
5512     m_currentPage = pageNum;
5513     m_paz.showPage(m_currentPage - 1);
5514   };
5515
5516
5517   that.pagerNext = function() {
5518     if (m_totalRecordCount - m_perpage*m_currentPage > 0) {
5519       m_paz.showNext();
5520       m_currentPage++;
5521     }
5522   };
5523
5524
5525   that.pagerPrev = function() {
5526     if (m_paz.showPrev() != false)
5527       m_currentPage--;
5528   };
5529
5530
5531   that.reShow = function() {
5532     resetPage();
5533     m_paz.show(0, m_perpage, m_sortOrder);
5534   };
5535
5536
5537   function resetPage() {
5538     m_currentPage = 1;
5539     m_totalRecordCount = 0;
5540     m_gotRecords = false;
5541   }
5542   that.resetPage = resetPage;
5543
5544
5545   function newSearch(query, sortOrder, maxrecs, perpage, limit, targets, torusquery) {
5546     log("newSearch: " + query);
5547
5548     if (config.use_service_proxy && !mkws.authenticated) {
5549       alert("searching before authentication");
5550       return;
5551     }
5552
5553     m_filterSet.removeMatching(function(f) { return f.type !== 'category' });
5554     triggerSearch(query, sortOrder, maxrecs, perpage, limit, targets, torusquery);
5555     switchView('records'); // In case it's configured to start off as hidden
5556     m_submitted = true;
5557   }
5558   that.newSearch = newSearch;
5559
5560
5561   function triggerSearch(query, sortOrder, maxrecs, perpage, limit, targets, torusquery) {
5562     resetPage();
5563     queue("navi").publish();
5564
5565     // Continue to use previous query/sort-order unless new ones are specified
5566     if (query) m_query = query;
5567     if (sortOrder) m_sortOrder = sortOrder;
5568     if (perpage) m_perpage = perpage;
5569     if (targets) m_filterSet.add(targetFilter(targets, targets));
5570
5571     var pp2filter = m_filterSet.pp2filter();
5572     var pp2limit = m_filterSet.pp2limit(limit);
5573     var pp2catLimit = m_filterSet.pp2catLimit();
5574     if (pp2catLimit) {
5575       pp2filter = pp2filter ? pp2filter + "," + pp2catLimit : pp2catLimit;
5576     }
5577
5578     var params = {};
5579     if (pp2limit) params.limit = pp2limit;
5580     if (maxrecs) params.maxrecs = maxrecs;
5581     if (torusquery) {
5582       if (!mkws.config.use_service_proxy)
5583         alert("can't narrow search by torusquery when not authenticated");
5584       params.torusquery = torusquery;
5585     }
5586
5587     log("triggerSearch(" + m_query + "): filters = " + m_filterSet.toJSON() + ", " +
5588         "pp2filter = " + pp2filter + ", params = " + $.toJSON(params));
5589
5590     m_paz.search(m_query, m_perpage, m_sortOrder, pp2filter, undefined, params);
5591   }
5592
5593   // fetch record details to be retrieved from the record queue
5594   that.fetchDetails = function(recId) {
5595     log("fetchDetails() requesting record '" + recId + "'");
5596     m_paz.record(recId);
5597   };
5598
5599
5600   // switching view between targets and records
5601   function switchView(view) {
5602     var targets = widgetNode('targets');
5603     var results = widgetNode('results') || widgetNode('records');
5604     var blanket = widgetNode('blanket');
5605     var motd    = widgetNode('motd');
5606
5607     switch(view) {
5608     case 'targets':
5609       if (targets) $(targets).show();
5610       if (results) $(results).hide();
5611       if (blanket) $(blanket).hide();
5612       if (motd) $(motd).hide();
5613       break;
5614     case 'records':
5615       if (targets) $(targets).hide();
5616       if (results) $(results).show();
5617       if (blanket) $(blanket).show();
5618       if (motd) $(motd).hide();
5619       break;
5620     default:
5621       alert("Unknown view '" + view + "'");
5622     }
5623   }
5624   that.switchView = switchView;
5625
5626
5627   // detailed record drawing
5628   that.showDetails = function(recId) {
5629     var oldRecordId = m_currentRecordId;
5630     m_currentRecordId = recId;
5631
5632     // remove current detailed view if any
5633     findnode('#' + recordDetailsId(oldRecordId)).remove();
5634
5635     // if the same clicked, just hide
5636     if (recId == oldRecordId) {
5637       m_currentRecordId = '';
5638       m_currentRecordData = null;
5639       return;
5640     }
5641     // request the record
5642     log("showDetails() requesting record '" + recId + "'");
5643     m_paz.record(recId);
5644   };
5645
5646
5647   // Finds the node of the specified class within the current team
5648   function findnode(selector, teamName) {
5649     teamName = teamName || m_teamName;
5650
5651     if (teamName === 'AUTO') {
5652       selector = (selector + '.mkws-team-' + teamName + ',' +
5653                   selector + ':not([class^="mkws-team"],[class*=" mkws-team"])');
5654     } else {
5655       selector = selector + '.mkws-team-' + teamName;
5656     }
5657
5658     var node = $(selector);
5659     //log('findnode(' + selector + ') found ' + node.length + ' nodes');
5660     return node;
5661   }
5662
5663
5664   function widgetNode(type) {
5665     var w = that.widget(type);
5666     return w ? w.node : undefined;
5667   }
5668
5669   function renderDetails(data, marker) {
5670     var template = loadTemplate("details");
5671     var details = template(data);
5672     return '<div class="mkws-details mkwsDetails mkwsTeam_' + m_teamName + '" ' +
5673       'id="' + recordDetailsId(data.recid[0]) + '">' + details + '</div>';
5674   }
5675   that.renderDetails = renderDetails;
5676
5677
5678   that.registerTemplate = function(name, text) {
5679     if(mkws._old2new.hasOwnProperty(name)) {
5680       mkws.log("Warning: registerTemplate old widget name: " + name + " => " + mkws._old2new[name]);
5681       name = mkws._old2new[name];
5682     }
5683     m_templateText[name] = text;
5684   };
5685
5686
5687   function loadTemplate(name, fallbackString) {
5688     if(mkws._old2new.hasOwnProperty(name)) {
5689        mkws.log("Warning loadTemplate: old widget name: " + name + " => " + mkws._old2new[name]);
5690        name = mkws._old2new[name];
5691     }
5692
5693     var template = m_template[name];
5694     if (template === undefined && Handlebars.compile) {
5695       var source;
5696       var node = $(".mkws-template-" + name + " .mkws-team-" + that.name());
5697       if (node && node.length < 1) {
5698         node = $(".mkws-template-" + name);
5699       }
5700       if (node) source = node.html();
5701       if (!source) source = m_templateText[name];
5702       if (source) {
5703         template = Handlebars.compile(source);
5704         log("compiled template '" + name + "'");
5705       }
5706     }
5707     //if (template === undefined) template = mkws_templatesbyteam[m_teamName][name];
5708     if (template === undefined && Handlebars.templates) {
5709       template = Handlebars.templates["mkws-template-" + name];
5710     }
5711     if (template === undefined && mkws.defaultTemplates) {
5712       template = mkws.defaultTemplates[name];
5713     }
5714     if (template) {
5715       m_template[name] = template;
5716       return template;
5717     }
5718     else {
5719       log("No MKWS template for " + name);
5720       return null;
5721     }  
5722   }
5723   that.loadTemplate = loadTemplate;
5724
5725
5726   that.addWidget = function(w) {
5727     if (m_widgets[w.type] === undefined) {
5728       m_widgets[w.type] = [ w ];
5729     } else {
5730       m_widgets[w.type].push(w);
5731     }
5732   }
5733
5734   that.widget = function(type) {
5735     var list = m_widgets[type];
5736
5737     if (!list)
5738       return undefined;
5739     if (list.length > 1) {
5740       alert("widget('" + type + "') finds " + list.length + " widgets: using first");
5741     }
5742     return list[0];
5743   }
5744
5745   that.visitWidgets = function(callback) {
5746     for (var type in m_widgets) {
5747       var list = m_widgets[type];
5748       for (var i = 0; i < list.length; i++) {
5749         var res = callback(type, list[i]);
5750         if (res !== undefined) {
5751           return res;
5752         }
5753       }
5754     }
5755     return undefined;
5756   }
5757
5758
5759   return that;
5760 };
5761 // Factory function for sets of filters.
5762 function filterSet(team) {
5763   var m_team = team;
5764   var m_list = [];
5765
5766   var that = {};
5767
5768   that.toJSON = function() {
5769     return mkws.$.toJSON(m_list);
5770   };
5771
5772   that.add = function(filter) {
5773     m_list.push(filter);
5774   };
5775
5776   that.visitTargets = function(callback) {
5777     for (var i in m_list) {
5778       var filter = m_list[i];
5779       if (filter.type === 'target') {
5780         callback(filter.id, filter.name);
5781       }
5782     }
5783   };
5784
5785   that.visitFields = function(callback) {
5786     for (var i in m_list) {
5787       var filter = m_list[i];
5788       if (filter.type === 'field') {
5789         callback(filter.field, filter.value);
5790       }
5791     }
5792   };
5793
5794   that.visitCategories = function(callback) {
5795     for (var i in m_list) {
5796       var filter = m_list[i];
5797       if (filter.type === 'category') {
5798         callback(filter.id);
5799       }
5800     }
5801   };
5802
5803   that.removeMatching = function(matchFn) {
5804     var newList = [];
5805     for (var i in m_list) {
5806       var filter = m_list[i];
5807       if (matchFn(filter)) {
5808         m_team.log("removeMatching: removing filter " + mkws.$.toJSON(filter));
5809       } else {
5810         m_team.log("removeMatching: keeping filter " + mkws.$.toJSON(filter));
5811         newList.push(filter);
5812       }
5813     }
5814     m_list = newList;
5815   };
5816
5817   that.targetFiltered = function(id) {
5818     for (var i = 0; i < m_list.length; i++) {
5819       if (m_list[i].type === 'target' ||
5820           m_list[i].id === 'pz:id=' + id) {
5821         return true;
5822       }
5823     }
5824     return false;
5825   };
5826
5827   that.pp2filter = function() {
5828     var res = "";
5829
5830     that.visitTargets(function(id, name) {
5831       if (res) res += ",";
5832       if (id.match(/^[a-z:]+[=~]/)) {
5833         m_team.log("filter '" + id + "' already begins with SETTING OP");
5834       } else {
5835         id = 'pz:id=' + id;
5836       }
5837       res += id;
5838     });
5839
5840     return res;
5841   };
5842
5843   that.pp2limit = function(initial) {
5844     var res = initial || "";
5845
5846     that.visitFields(function(field, value) {
5847       if (res) res += ",";
5848       res += field + "=" + value.replace(/[\\|,]/g, '\\$&');
5849     });
5850     return res;
5851   }
5852
5853   that.pp2catLimit = function() {
5854     var res = "";
5855
5856     that.visitCategories(function(id) {
5857       if (res) res += ",";
5858       res += "category~" + id.replace(/[\\|,]/g, '\\$&');
5859     });
5860     return res;
5861   }
5862
5863   return that;
5864 }
5865
5866
5867 // Factory functions for filters. These can be of several types.
5868 function targetFilter(id, name) {
5869   return {
5870     type: 'target',
5871     id: id,
5872     name: name
5873   };
5874 }
5875
5876 function fieldFilter(field, value) {
5877   return {
5878     type: 'field',
5879     field: field,
5880     value: value
5881   };
5882 }
5883
5884 function categoryFilter(id) {
5885   return {
5886     type: 'category',
5887     id: id
5888   };
5889 }
5890 // Factory function for widget objects.
5891 mkws.makeWidget = function($, team, type, node) {
5892   // Static register of attributes that do not contribute to config
5893   var ignoreAttrs = {
5894     id:1, 'class':1, style:1, name:1, action:1, type:1, size:1,
5895     value:1, width:1, valign:1
5896   };
5897
5898   var that = {
5899     team: team,
5900     type: type,
5901     node: $(node),
5902     config: mkws.objectInheritingFrom(team.config)
5903   };
5904
5905   function log(s) {
5906     team.log(s);
5907   }
5908   that.log = log;
5909
5910   that.toString = function() {
5911     return '[Widget ' + team.name() + ':' + type + ']';
5912   };
5913
5914   that.value = function() {
5915     return node.value;
5916   };
5917
5918   // Returns the HTML of a subwidget of the specified type. It gets
5919   // the same attributes at the parent widget that invokes this
5920   // function, except where overrides are passed in. If defaults are
5921   // also provided, then these are used when the parent widget
5922   // provides no values.
5923   that.subwidget = function(type, overrides, defaults) {
5924     var attrs = { _team: team.name() };
5925     
5926     // Copy locally-set properties from the parent widget
5927     for (var name in this.config) {
5928       if (this.config.hasOwnProperty(name)) {
5929         attrs[name] = this.config[name];
5930         log(this + " copied property " + name + "='" + attrs[name] + "' to " + type + " subwidget");
5931       }
5932     }
5933     
5934     for (var name in overrides) {
5935       log(this + " overrode property " + name + "='" + overrides[name] + "' (was '" + attrs[name] + "') for " + type + " subwidget");
5936       attrs[name] = overrides[name];
5937     }
5938
5939     if (defaults) {
5940       for (var name in defaults) {
5941         if (!attrs[name]) {
5942           attrs[name] = defaults[name];
5943           log(this + " fell back to default property " + name + "='" + attrs[name] + "' for " + type + " subwidget");
5944         }
5945       }
5946     }
5947
5948     var s = [];
5949     s.push('<div class="mkws', type, ' mkws-team-', attrs._team, '"');
5950     for (var name in attrs) {    
5951       if (name !== '_team')
5952         s.push(' ', name, '="', attrs[name], '"');
5953     }
5954     s.push('></div>');
5955     return s.join('');
5956   };
5957
5958   function expandValue(val) {
5959     if (val.match(/^!param!/)) {
5960       var param = val.replace(/^!param!/, '');
5961       val = mkws.getParameterByName(param);
5962       log("obtained val '" + val + "' from param '" + param + "'");
5963       if (!val) {
5964         alert("This page has a MasterKey widget that needs a val specified by the '" + param + "' parameter");
5965       }
5966     } else if (val.match(/^!path!/)) {
5967       var index = val.replace(/^!path!/, '');
5968       var path = window.location.pathname.split('/');
5969       val = path[path.length - index];
5970       log("obtained val '" + val + "' from path-component '" + index + "'");
5971       if (!val) {
5972         alert("This page has a MasterKey widget that needs a val specified by the path-component " + index);
5973       }
5974     } else if (val.match(/^!var!/)) {
5975       var name = val.replace(/^!var!/, '');
5976       val = window[name]; // It's ridiculous that this works
5977       log("obtained val '" + val + "' from variable '" + name + "'");
5978       if (!val) {
5979         alert("This page has a MasterKey widget that needs a val specified by the '" + name + "' variable");
5980       }
5981     }
5982     return val;
5983   };
5984
5985   // Utility function for use by all widgets that can invoke autosearch.
5986   that.autosearch = function() {
5987     var that = this;
5988     var query = this.config.autosearch;
5989     if (query) {
5990       var old = this.team.config.query;
5991       if (!old) {
5992         // Stash this for subsequent inspection
5993         this.team.config.query = query;
5994       } else if (old === query) {
5995         this.log("duplicate autosearch: '" + query + "': ignoring");
5996         return;
5997       } else {
5998         this.log("conflicting autosearch: '" + query + "' vs '" + old + "': ignoring");
5999         return;
6000       }
6001
6002       this.team.queue("ready").subscribe(function() {
6003         // Postpone testing for the configuration items: these are not
6004         // yet set for Record subclass widgets that fill them in in the
6005         // subclass, as widget.autosearch is called in the superclass,
6006         // before the subclass fiddles with the configuration.
6007         var sortOrder = that.config.sort;
6008         var maxrecs = that.config.maxrecs;
6009         var perpage = that.config.perpage;
6010         var limit = that.config.limit;
6011         var targets = that.config.targets;
6012         var targetfilter = that.config.targetfilter;
6013         var target = that.config.target;
6014         if (target) targetfilter = 'udb=="' + target + '"';
6015
6016         var s = "running auto search: '" + query + "'";
6017         if (sortOrder) s += " sorted by '" + sortOrder + "'";
6018         if (maxrecs) s += " restricted to " + maxrecs + " records";
6019         if (perpage) s += " with " + perpage + " per page";
6020         if (limit) s += " limited by '" + limit + "'";
6021         if (targets) s += " in targets '" + targets + "'";
6022         if (targetfilter) s += " constrained by targetfilter '" + targetfilter + "'";
6023         that.log(s);
6024
6025         that.team.newSearch(query, sortOrder, maxrecs, perpage, limit, targets, targetfilter);
6026       });
6027     }
6028   };
6029
6030   // Utility function for all widgets that want to hide in narrow windows
6031   that.hideWhenNarrow = function() {
6032     var that = this;
6033     this.team.queue("resize-narrow").subscribe(function(n) {
6034       that.node.hide();
6035     });
6036     this.team.queue("resize-wide").subscribe(function(n) {
6037       that.node.show();
6038     });
6039   };
6040
6041
6042   for (var i = 0; i < node.attributes.length; i++) {
6043     var a = node.attributes[i];
6044     var val = expandValue(a.value);
6045     if (a.name === 'data-mkws-config') {
6046       // Treat as a JSON fragment configuring just this widget
6047       log(node + ": parsing config fragment '" + val + "'");
6048       var data;
6049       try {
6050         data = $.parseJSON(val);
6051         for (var key in data) {
6052           log(node + ": adding config element " + key + "='" + data[key] + "'");
6053           that.config[key] = data[key];
6054         }
6055       } catch (err) {
6056         alert("Can't parse " + node + " data-mkws-config as JSON: " + val);
6057       }
6058     } else if (a.name.match (/^data-mkws-/)) {
6059       var name = a.name.replace(/^data-mkws-/, '')
6060       that.config[name] = val;
6061       log(that + ": set data-mkws attribute " + name + "='" + val + "'");
6062     } else if (!ignoreAttrs[a.name]) {
6063       that.config[a.name] = val;
6064       log(that + ": set regular attribute " + a.name + "='" + val + "'");
6065     }
6066   }
6067
6068   var fn = mkws.promotionFunction(type);
6069   if (fn) {
6070     fn.call(that);
6071     log("made " + type + " widget(node=" + node + ")");
6072   } else if (type.match(/-Container-(narrow|wide)$/)) {
6073     // Not really a widget: no need to log its lack of promotion
6074   } else {
6075     log("made UNPROMOTED widget(type=" + type + ", node=" + node + ")");
6076   }
6077
6078   return that;
6079 };
6080 (function($) { // jQuery wrapper
6081
6082 // Functions follow for promoting the regular widget object into
6083 // widgets of specific types. These could be moved into their own
6084 // source files.
6085
6086
6087 mkws.registerWidgetType('targets', function() {
6088   if (!this.config.show_switch) return;
6089   var that = this;
6090
6091   this.node.html('No information available yet.');
6092   this.node.css("display", "none");
6093
6094   this.team.queue("targets").subscribe(function(data) {
6095     // There is a bug in pz2.js wherein it makes each data object an array but
6096     // simply assigns properties to it.
6097     // TODO: remove this when PAZ-946 is addressed.
6098     var cleandata = [];
6099     for (var i = 0; i < data.length; i++) {
6100       var cur = {};
6101       cur.id = data[i].id;
6102       cur.hits = data[i].hits;
6103       cur.diagnostic = data[i].diagnostic;
6104       cur.message = data[i].message;
6105       cur.records = data[i].records;
6106       cur.state = data[i].state;
6107       cleandata.push(cur);
6108     }
6109
6110     var template = that.team.loadTemplate(that.config.template || "targets");
6111     that.node.html(template({data: cleandata}));
6112   });
6113 });
6114
6115
6116 mkws.registerWidgetType('stat', function() {
6117   var that = this;
6118   this.team.queue("stat").subscribe(function(data) {
6119     var template = that.team.loadTemplate(that.config.template || "stat");
6120     that.node.html(template(data));
6121   });
6122 });
6123
6124
6125 mkws.registerWidgetType('pager', function() {
6126   var that = this;
6127   var M = mkws.M;
6128
6129   this.team.queue("pager").subscribe(function(data) {
6130     var teamName = that.team.name();
6131     var output = {};
6132     output.first = data.start + 1;
6133     output.last = data.start + data.num;
6134     output.count = data.merged;
6135     output.found = data.total;
6136
6137     //client indexes pages from 1 but pz2 from 0
6138     var onsides = 5;
6139     var pages = Math.ceil(that.team.totalRecordCount() / that.team.perpage());
6140     var currentPage = that.team.currentPage();
6141
6142     var firstClkbl = (currentPage - onsides > 0)
6143       ? currentPage - onsides
6144       : 1;
6145     var lastClkbl = firstClkbl + 2*onsides < pages
6146       ? firstClkbl + 2*onsides
6147       : pages;
6148
6149     if (firstClkbl > 1) output.morePrev = true;
6150     if (lastClkbl < pages) output.moreNext = true;
6151
6152     if (currentPage > 1) output.prevClick = "mkws.pagerPrev(\'" + teamName + "\');";
6153
6154     output.pages = [];
6155     for(var i = firstClkbl; i <= lastClkbl; i++) {
6156       var o = {};
6157       o.number = i;
6158       if (i !== currentPage) {
6159         o.click = "mkws.showPage(\'" + teamName + "\', " + i + ");";
6160       }
6161       output.pages.push(o);
6162     }
6163
6164     if (pages - currentPage > 0) output.nextClick = "mkws.pagerNext(\'" + teamName + "\')";
6165
6166     var template = that.team.loadTemplate(that.config.template || "pager");
6167     that.node.html(template(output));
6168   });
6169 });
6170
6171 mkws.registerWidgetType('details', function() {
6172   var that = this;
6173   var recid = that.node.attr("data-mkws-recid");
6174   if (this.team.gotRecords()) { 
6175     that.team.fetchDetails(recid);
6176   } else {
6177     this.team.queue("firstrecords").subscribe(function() {
6178       that.team.fetchDetails(recid);
6179     });
6180   }
6181   this.team.queue("record").subscribe(function(data) {
6182     if ($.inArray(recid, data.recid) > -1) {
6183       var template = that.team.loadTemplate(that.config.template || "details");
6184       that.node.html(template(data));
6185     }
6186   });
6187 });
6188
6189 mkws.registerWidgetType('records', function() {
6190   var that = this;
6191   var team = this.team;
6192
6193   this.team.queue("records").subscribe(function(data) {
6194     for (var i = 0; i < data.hits.length; i++) {
6195       var hit = data.hits[i];
6196       hit.detailLinkId = team.recordElementId(hit.recid[0]);
6197       hit.detailClick = "mkws.showDetails('" + team.name() + "', '" + hit.recid[0] + "');return false;";
6198       hit.containerClass = "mkws-summary mkwsSummary mkws-team-" + team.name();
6199       hit.containerClass += " " + hit.detailLinkId;
6200       // ### At some point, we may be able to move the
6201       // m_currentRecordId and m_currentRecordData members
6202       // from the team object into this widget.
6203       if (hit.recid == team.currentRecordId()) {
6204         if (team.currentRecordData()) {
6205           hit.renderedDetails = team.renderDetails(team.currentRecordData());
6206         } 
6207       }
6208     }
6209     var template = team.loadTemplate(that.config.template || "records");
6210     var summaryPartial = team.loadTemplate(that.config['summary-template'] || "summary");
6211     var tdata = $.extend({}, {"hits": data.hits}, that.config.template_vars);
6212     that.node.html(template(tdata, {"partials":{"summary":summaryPartial}}));
6213   });
6214
6215   that.autosearch();
6216 });
6217
6218
6219 mkws.registerWidgetType('navi', function() {
6220   var that = this;
6221   var teamName = this.team.name();
6222
6223   this.team.queue("navi").subscribe(function() {
6224     var filters = that.team.filters();
6225     var output = {filters:[]};
6226
6227     filters.visitTargets(function(id, name) {
6228       var cur = {};
6229       cur.facet = 'source';
6230       cur.value = name;
6231       cur.click = "mkws.delimitTarget('" + teamName + "', '" + id + "'); return false;";
6232       output.filters.push(cur);
6233     });
6234
6235     filters.visitFields(function(field, value) {
6236       var cur = {};
6237       cur.facet = field;
6238       cur.value = value;
6239       cur.click = "mkws.delimitQuery('" + teamName + "', '" + field + "', '" + value + "'" + ");return false;";
6240       output.filters.push(cur);
6241     });
6242
6243     var template = that.team.loadTemplate(that.config.template || "navi");
6244     that.node.html(template(output));
6245   });
6246 });
6247
6248
6249 // It seems this and the Perpage widget doen't need to subscribe to
6250 // anything, since they produce events rather than consuming them.
6251 //
6252 mkws.registerWidgetType('sort', function() {
6253   var that = this;
6254
6255   this.node.change(function() {
6256     that.team.set_sortOrder(that.node.val());
6257     if (that.team.submitted()) {
6258       that.team.reShow();
6259     }
6260     return false;
6261   });
6262 });
6263
6264
6265 mkws.registerWidgetType('per-page', function() {
6266   var that = this;
6267
6268   this.node.change(function() {
6269     that.team.set_perpage(that.node.val());
6270     if (that.team.submitted()) {
6271       that.team.reShow();
6272     }
6273     return false;
6274   });
6275 });
6276
6277
6278 mkws.registerWidgetType('done', function() {
6279   var that = this;
6280   this.team.queue("complete").subscribe(function(n) {
6281     var template = that.team.loadTemplate(that.config.template || "done");
6282     that.node.html(template({count: n}));
6283   });
6284 });
6285
6286
6287 mkws.registerWidgetType('switch', function() {
6288   if (!this.config.show_switch) return;
6289   var tname = this.team.name();
6290   var output = {};
6291   output.recordClick = "mkws.switchView(\'" + tname + "\', \'records\')";
6292   output.targetClick = "mkws.switchView(\'" + tname + "\', \'targets\')";
6293   var template = this.team.loadTemplate(this.config.template || "switch");
6294   this.node.html(template(output));
6295   this.hideWhenNarrow();
6296 });
6297
6298
6299 mkws.registerWidgetType('search', function() {
6300   var output = {};
6301   output.team = this.team.name();
6302   var template = this.team.loadTemplate(this.config.template || "search");
6303   this.node.html(template(output));
6304 });
6305
6306
6307 mkws.registerWidgetType('search-form', function() {
6308   var team = this.team;
6309   this.node.submit(function() {
6310     var val = team.widget('query').value();
6311     team.newSearch(val);
6312     return false;
6313   });
6314 });
6315
6316
6317 mkws.registerWidgetType('results', function() {
6318   var template = this.team.loadTemplate(this.config.template || "results");
6319   this.node.html(template({team: this.team.name()}));
6320   this.autosearch();
6321 });
6322
6323
6324 mkws.registerWidgetType('ranking', function() {
6325   var output = {};
6326   output.perPage = [];
6327   output.sort = [];
6328   output.team = this.team.name();
6329   output.showSort = this.config.show_sort;
6330   output.showPerPage = this.config.show_perpage;
6331
6332   var order = this.team.sortOrder();
6333   this.log("making sort, sortOrder = '" + order + "'");
6334   for (var i = 0; i < this.config.sort_options.length; i++) {
6335     var cur = {};
6336     var opt = this.config.sort_options[i];
6337     cur.key = opt[0];
6338     cur.label = opt.length == 1 ? opt[0] : opt[1];
6339     if (order == cur.key || order == cur.label) cur.selected = true;
6340     output.sort.push(cur);
6341   }
6342
6343   var perpage = this.team.perpage();
6344   this.log("making perpage, perpage = " + perpage);
6345   for(var i = 0; i < this.config.perpage_options.length; i++) {
6346     var cur = {};
6347     cur.perPage = this.config.perpage_options[i];
6348     if (cur.perPage == perpage) cur.selected = true;
6349     output.perPage.push(cur);
6350   }
6351
6352   var template = this.team.loadTemplate(this.config.template || "ranking");
6353   this.node.html(template(output));
6354 });
6355
6356
6357 mkws.registerWidgetType('lang', function() {
6358   // dynamic URL or static page? /path/foo?query=test
6359   /* create locale language menu */
6360   if (!this.config.show_lang) return;
6361
6362   var lang_default = "en";
6363   var lang = this.config.lang || lang_default;
6364   var list = [];
6365
6366   /* display a list of configured languages, or all */
6367   var lang_options = this.config.lang_options;
6368   var toBeIncluded = {};
6369   for (var i = 0; i < lang_options.length; i++) {
6370     toBeIncluded[lang_options[i]] = true;
6371   }
6372
6373   for (var k in mkws.locale_lang) {
6374     if (toBeIncluded[k] || lang_options.length == 0) {
6375       cur = {};
6376       if (lang === k) cur.selected = true;
6377       cur.code = k;
6378       cur.url = lang_url(k);
6379       list.push(cur);
6380     }
6381   }
6382
6383   // add english link
6384   if (lang_options.length == 0 || toBeIncluded[lang_default]) {
6385       cur = {};
6386       if (lang === lang_default) cur.selected = true;
6387       cur.code = lang_default;
6388       cur.url = lang_url(lang_default);
6389       list.push(cur);
6390   }
6391
6392   this.log("language menu: " + list.join(", "));
6393
6394   var template = this.team.loadTemplate(this.config.template || "lang");
6395   this.node.html(template({languages: list}));
6396   this.hideWhenNarrow();
6397
6398   // set or re-set "lang" URL parameter
6399   function lang_url(lang) {
6400     var query = location.search;
6401     // no query parameters? done
6402     if (!query) {
6403       return "?lang=" + lang;
6404     }
6405
6406     // parameter does not exist
6407     if (!query.match(/[\?&]lang=/)) {
6408       return query + "&lang=" + lang;
6409     }
6410
6411     // replace existing parameter
6412     query = query.replace(/\?lang=([^&#;]*)/, "?lang=" + lang);
6413     query = query.replace(/\&lang=([^&#;]*)/, "&lang=" + lang);
6414     return query;
6415   }
6416 });
6417
6418
6419 mkws.registerWidgetType('motd', function() {
6420   var container = this.team.widget('motd-container');
6421   if (container) {
6422     // Move the MOTD from the provided element down into the container
6423     this.node.appendTo(container.node);
6424   }
6425 });
6426
6427
6428 // This widget has no functionality of its own, but its configuration
6429 // is copied up into its team, allowing it to affect other widgets in
6430 // the team.
6431 //
6432 mkws.registerWidgetType('config', function() {
6433   var c = this.config;
6434   for (var name in c) {
6435     if (c.hasOwnProperty(name)) {
6436       this.team.config[name] = c[name];
6437       this.log(this + " copied property " + name + "='" + c[name] + "' up to team");
6438     }
6439   }
6440 });
6441
6442
6443 mkws.registerWidgetType('progress', function() {
6444   var that = this;
6445   this.node.hide();
6446   this.team.queue("stat").subscribe(function(data) {
6447     var template = that.team.loadTemplate(that.config.template || "progress");
6448     that.node.html(template({
6449       done: data.clients - data.activeclients,
6450       waiting: data.activeclients
6451     }));
6452     that.node.show();
6453   });
6454 });
6455
6456
6457 // Some elements have mkws* classes that makes them appear as widgets
6458 // -- for example, because we want to style them using CSS -- but have
6459 // no actual functionality. We register these to prevent ignorable
6460 // warnings when they occur.
6461
6462 mkws.registerWidgetType('query', function() {});
6463 mkws.registerWidgetType('motd-container', function() {});
6464 mkws.registerWidgetType('button', function() {});
6465
6466
6467 })(mkws.$); // jQuery wrapper
6468 mkws.registerWidgetType('facets', function() {
6469   // Initially hide the facets; display when we get results
6470   var that = this;
6471   var team = this.team;
6472   team.queue("facets").subscribe(function(data) {
6473     that.node.addClass("active");
6474   });
6475
6476   var template = team.loadTemplate(this.config.template || "facets");
6477   this.node.html(template({
6478     team: team.name(),
6479     facets: this.config.facets
6480   }));
6481   this.autosearch();
6482 });
6483
6484
6485 mkws.registerWidgetType('facet', function() {
6486   var facetConfig = {
6487     xtargets: [ "Sources",  16, false ],
6488     subject:  [ "Subjects", 10, true ],
6489     author:   [ "Authors",  10, true ]
6490   }
6491   var that = this;
6492   var team = this.team;
6493   var name = that.config.facet;
6494   var ref = facetConfig[name] || [ "Unknown", 10, true ];
6495   var caption = this.config['facet_caption_' + name] || ref[0];
6496   var max     = parseInt(this.config['facet_max_' + name] || ref[1]);
6497   var pzIndex = ref[2] ? name : null;
6498
6499   that.toString = function() {
6500     return '[Widget ' + team.name() + ':' + that.type + '(' + name + ')]';
6501   };
6502
6503   team.queue("facets").subscribe(function(data) {
6504     data = data[name];
6505     var terms = [];
6506     var teamName = team.name();
6507     for (var i = 0; i < data.length && i < max; i++) {
6508       var linkdata = "";
6509       var action = "";
6510       if (!pzIndex) {
6511         // Special case: target selection
6512         linkdata += ('target_id='+data[i].id+' ');
6513         if (!team.targetFiltered(data[i].id)) {
6514           action = 'mkws.limitTarget(\'' + teamName + '\', this.getAttribute(\'target_id\'),this.firstChild.nodeValue)';
6515         }
6516       } else {
6517         action = 'mkws.limitQuery(\'' + teamName + '\', \'' + pzIndex + '\', this.firstChild.nodeValue)';
6518       }
6519       linkdata += 'onclick="' + action + ';return false;"';
6520       terms.push({
6521         term: data[i].name,
6522         field: data[i].id,
6523         count: data[i].freq,
6524         linkdata: linkdata
6525       }); 
6526     }
6527     // configured template > facet specific template > default facet template
6528     var template;
6529     if (that.config.template) {
6530       template = team.loadTemplate(that.config.template);
6531     } else {
6532       template = team.loadTemplate("facet-" + name);
6533       if (template) {
6534         that.log("Using facet-" + name + " template.")
6535       } else {
6536         that.log("No " + name + " specific template, using default.")
6537         template = team.loadTemplate("facet");
6538       }
6539     }
6540     that.node.html(template({
6541       name: name,
6542       caption: caption,
6543       query: that.config.query,
6544       terms: terms
6545     }));
6546   });
6547   this.autosearch();
6548 });
6549 mkws.registerWidgetType('auth-name', function() {
6550   var that = this;
6551
6552   this.team.queue("authenticated").subscribe(function(authName) {
6553     that.node.html(authName);
6554   });
6555 });
6556 mkws.registerWidgetType('categories', function() {
6557   var that = this;
6558
6559   if (!mkws.authenticated) {
6560     alert("can't use categories widget when not authenticated");
6561     return;
6562   }
6563
6564   this.team.queue("authenticated").subscribe(function(authName, realm) {
6565     var req = new pzHttpRequest(mkws.pazpar2_url() + "?command=categories", function(err) {
6566       alert("HTTP call for categories failed: " + err)
6567     });
6568
6569     req.get(null, function(data) {
6570       if (!$.isXMLDoc(data)) {
6571         alert("categories response document is not XML");
6572         return;
6573       }
6574       that.log("got categories: " + data);
6575
6576       var text = [];
6577       text.push("Select category: ");
6578       text.push("<select name='mkws-category mkwsCategory' " +
6579                 "onchange='mkws.limitCategory(\"" + that.team.name() + "\", this.value)'>");
6580       text.push("<option value=''>[All]</option>");
6581       $(data).find('category').each(function() {
6582         var name = $(this).find('categoryName').text();
6583         var id = $(this).find('categoryId').text();
6584         text.push("<option value='", id, "'>", name, "</option>");
6585       });
6586       text.push("</select>");
6587       that.node.html(text.join(''));
6588     });
6589   });
6590 });
6591 mkws.registerWidgetType('log', function() {
6592   var that = this;
6593
6594   this.team.queue("log").subscribe(function(teamName, timestamp, message) {
6595     that.node.append(teamName + ": " + timestamp + message + "<br/>");
6596   });
6597 });
6598 // A widget for a record-list of a single record
6599 mkws.registerWidgetType('record', function() {
6600   if (!this.config.maxrecs) this.config.maxrecs = 1;
6601   var that = this;
6602   var team = this.team;
6603   team.queue("records").subscribe(function(data) {
6604     var template = team.loadTemplate(that.config.template || "details");
6605     var targs = mkws.$.extend({}, data.hits[0], that.config.template_vars);
6606     that.node.html(template(targs));
6607   });
6608   that.autosearch();
6609 });
6610
6611 mkws.registerWidgetType('images', function() {
6612   mkws.promotionFunction('records').call(this);
6613   if (!this.config.template) this.config.template = 'images';
6614 });
6615
6616 mkws.registerWidgetType('google-image', function() {
6617   mkws.promotionFunction('images').call(this);
6618   if (!this.config.target) this.config.target = 'Google_Images';
6619 });
6620
6621 mkws.registerWidgetType('lolcat', function() {
6622   mkws.promotionFunction('google-image').call(this);
6623   if (!this.config.autosearch) this.config.autosearch = 'kitteh';
6624 });
6625
6626 mkws.registerWidgetType('cover-art', function() {
6627   mkws.promotionFunction('images').call(this);
6628   if (!this.config.target) this.config.target = 'AmazonBooks';
6629 });
6630 mkws.registerWidgetType('reference', function() {
6631   mkws.promotionFunction('record').call(this);
6632   if (!this.config.target) this.config.target = 'wikimedia_wikipedia_single_result';
6633   if (!this.config.template) this.config.template = 'reference';
6634   this.config.template_vars.paragraphs = this.config.paragraphs || 0;
6635   this.config.template_vars.sentences = this.config.sentences || 0;
6636 });
6637 mkws.registerWidgetType('builder', function() {
6638   var that = this;
6639   var team = this.team;
6640
6641   var button = mkws.$('<button/>', {
6642     type: 'button',
6643     text: this.config.text || "Build!"
6644   });
6645   this.node.append(button);
6646   button.click(function() {
6647     var   query = team.widget('query').value();
6648     var    sort = team.widget('sort').value();
6649     var perpage = team.widget('per-page').value();
6650
6651     var html = ('<div class="mkws-records mkwsRecords" ' +
6652                 'autosearch="' + query + '" ' +
6653                 'sort="' + sort + '" ' +
6654                 'perpage="' + perpage + '"></div>');
6655     var fn = that.callback || alert;
6656     fn(html);
6657   });
6658 });
6659
6660 mkws.registerWidgetType('console-builder', function() {
6661   mkws.promotionFunction('builder').call(this);
6662   this.callback = function(s) {
6663     console.log("generated widget: " + s);
6664   }
6665 });
6666 (function() {
6667   var template = Handlebars.template, templates = mkws.defaultTemplates = mkws.defaultTemplates || {};
6668 templates['details'] = template({"1":function(depth0,helpers,partials,data) {
6669   var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
6670   return "        ("
6671     + escapeExpression(((helper = (helper = helpers['md-title-remainder'] || (depth0 != null ? depth0['md-title-remainder'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"md-title-remainder","hash":{},"data":data}) : helper)))
6672     + ")\n";
6673 },"3":function(depth0,helpers,partials,data) {
6674   var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
6675   return "        <i>"
6676     + escapeExpression(((helper = (helper = helpers['md-title-responsibility'] || (depth0 != null ? depth0['md-title-responsibility'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"md-title-responsibility","hash":{},"data":data}) : helper)))
6677     + "</i>\n";
6678 },"5":function(depth0,helpers,partials,data) {
6679   var helper, helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, functionType="function";
6680   return "  <tr>\n    <th>"
6681     + escapeExpression(((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "Date", {"name":"mkws-translate","hash":{},"data":data})))
6682     + "</th>\n    <td>"
6683     + escapeExpression(((helper = (helper = helpers['md-date'] || (depth0 != null ? depth0['md-date'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"md-date","hash":{},"data":data}) : helper)))
6684     + "</td>\n  </tr>\n";
6685 },"7":function(depth0,helpers,partials,data) {
6686   var helper, helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, functionType="function";
6687   return "  <tr>\n    <th>"
6688     + escapeExpression(((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "Author", {"name":"mkws-translate","hash":{},"data":data})))
6689     + "</th>\n    <td>"
6690     + escapeExpression(((helper = (helper = helpers['md-author'] || (depth0 != null ? depth0['md-author'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"md-author","hash":{},"data":data}) : helper)))
6691     + "</td>\n  </tr>\n";
6692 },"9":function(depth0,helpers,partials,data) {
6693   var stack1, helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "  <tr>\n    <th>"
6694     + escapeExpression(((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "Links", {"name":"mkws-translate","hash":{},"data":data})))
6695     + "</th>\n    <td>\n";
6696   stack1 = helpers.each.call(depth0, (depth0 != null ? depth0['md-electronic-url'] : depth0), {"name":"each","hash":{},"fn":this.program(10, data),"inverse":this.noop,"data":data});
6697   if (stack1 != null) { buffer += stack1; }
6698   return buffer + "    </td>\n  </tr>\n";
6699 },"10":function(depth0,helpers,partials,data) {
6700   var helper, lambda=this.lambda, escapeExpression=this.escapeExpression, functionType="function", helperMissing=helpers.helperMissing;
6701   return "        <a href=\""
6702     + escapeExpression(lambda(depth0, depth0))
6703     + "\">Link"
6704     + escapeExpression(((helper = (helper = helpers['mkws-index1'] || (depth0 != null ? depth0['mkws-index1'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"mkws-index1","hash":{},"data":data}) : helper)))
6705     + "</a>\n";
6706 },"12":function(depth0,helpers,partials,data) {
6707   var stack1, helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "  <tr>\n    <th>"
6708     + escapeExpression(((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "Subject", {"name":"mkws-translate","hash":{},"data":data})))
6709     + "</th>\n    <td>\n";
6710   stack1 = ((helpers['mkws-first'] || (depth0 && depth0['mkws-first']) || helperMissing).call(depth0, (depth0 != null ? depth0.location : depth0), {"name":"mkws-first","hash":{
6711     'having': ("md-subject")
6712   },"fn":this.program(13, data),"inverse":this.noop,"data":data}));
6713   if (stack1 != null) { buffer += stack1; }
6714   return buffer + "    </td>\n  </tr>\n";
6715 },"13":function(depth0,helpers,partials,data) {
6716   var stack1, buffer = "";
6717   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0['md-subject'] : depth0), {"name":"if","hash":{},"fn":this.program(14, data),"inverse":this.noop,"data":data});
6718   if (stack1 != null) { buffer += stack1; }
6719   return buffer;
6720 },"14":function(depth0,helpers,partials,data) {
6721   var stack1, helperMissing=helpers.helperMissing, buffer = "";
6722   stack1 = ((helpers['mkws-commaList'] || (depth0 && depth0['mkws-commaList']) || helperMissing).call(depth0, (depth0 != null ? depth0['md-subject'] : depth0), {"name":"mkws-commaList","hash":{},"fn":this.program(15, data),"inverse":this.noop,"data":data}));
6723   if (stack1 != null) { buffer += stack1; }
6724   return buffer + "\n";
6725 },"15":function(depth0,helpers,partials,data) {
6726   var lambda=this.lambda, escapeExpression=this.escapeExpression;
6727   return "            "
6728     + escapeExpression(lambda(depth0, depth0));
6729 },"17":function(depth0,helpers,partials,data) {
6730   var helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
6731   return "        "
6732     + escapeExpression(((helpers['mkws-attr'] || (depth0 && depth0['mkws-attr']) || helperMissing).call(depth0, "@name", {"name":"mkws-attr","hash":{},"data":data})));
6733 },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
6734   var stack1, helper, helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, functionType="function", buffer = "<table>\n  <tr>\n    <th>"
6735     + escapeExpression(((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "Title", {"name":"mkws-translate","hash":{},"data":data})))
6736     + "</th>\n    <td>\n      "
6737     + escapeExpression(((helper = (helper = helpers['md-title'] || (depth0 != null ? depth0['md-title'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"md-title","hash":{},"data":data}) : helper)))
6738     + "\n";
6739   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0['md-title-remainder'] : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data});
6740   if (stack1 != null) { buffer += stack1; }
6741   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0['md-title-responsibility'] : depth0), {"name":"if","hash":{},"fn":this.program(3, data),"inverse":this.noop,"data":data});
6742   if (stack1 != null) { buffer += stack1; }
6743   buffer += "    </td>\n  </tr>\n";
6744   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0['md-date'] : depth0), {"name":"if","hash":{},"fn":this.program(5, data),"inverse":this.noop,"data":data});
6745   if (stack1 != null) { buffer += stack1; }
6746   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0['md-author'] : depth0), {"name":"if","hash":{},"fn":this.program(7, data),"inverse":this.noop,"data":data});
6747   if (stack1 != null) { buffer += stack1; }
6748   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0['md-electronic-url'] : depth0), {"name":"if","hash":{},"fn":this.program(9, data),"inverse":this.noop,"data":data});
6749   if (stack1 != null) { buffer += stack1; }
6750   stack1 = ((helpers['mkws-if-any'] || (depth0 && depth0['mkws-if-any']) || helperMissing).call(depth0, (depth0 != null ? depth0.location : depth0), {"name":"mkws-if-any","hash":{
6751     'having': ("md-subject")
6752   },"fn":this.program(12, data),"inverse":this.noop,"data":data}));
6753   if (stack1 != null) { buffer += stack1; }
6754   buffer += "  <tr>\n    <th>"
6755     + escapeExpression(((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "Locations", {"name":"mkws-translate","hash":{},"data":data})))
6756     + "</th>\n    <td>\n";
6757   stack1 = ((helpers['mkws-commaList'] || (depth0 && depth0['mkws-commaList']) || helperMissing).call(depth0, (depth0 != null ? depth0.location : depth0), {"name":"mkws-commaList","hash":{},"fn":this.program(17, data),"inverse":this.noop,"data":data}));
6758   if (stack1 != null) { buffer += stack1; }
6759   return buffer + "\n    </td>\n  </tr>\n</table>\n";
6760 },"useData":true});
6761 templates['done'] = template({"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
6762   var stack1, helper, helperMissing=helpers.helperMissing, functionType="function", escapeExpression=this.escapeExpression, buffer = "";
6763   stack1 = ((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "Search complete: found", {"name":"mkws-translate","hash":{},"data":data}));
6764   if (stack1 != null) { buffer += stack1; }
6765   buffer += " "
6766     + escapeExpression(((helper = (helper = helpers.count || (depth0 != null ? depth0.count : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"count","hash":{},"data":data}) : helper)))
6767     + " ";
6768   stack1 = ((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "records", {"name":"mkws-translate","hash":{},"data":data}));
6769   if (stack1 != null) { buffer += stack1; }
6770   return buffer + "\n\n";
6771 },"useData":true});
6772 templates['facet'] = template({"1":function(depth0,helpers,partials,data) {
6773   var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "  <div class=\"mkws-term mkwsTerm\">\n    <a href=\"#\" ";
6774   stack1 = ((helper = (helper = helpers.linkdata || (depth0 != null ? depth0.linkdata : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"linkdata","hash":{},"data":data}) : helper));
6775   if (stack1 != null) { buffer += stack1; }
6776   return buffer + ">"
6777     + escapeExpression(((helper = (helper = helpers.term || (depth0 != null ? depth0.term : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"term","hash":{},"data":data}) : helper)))
6778     + "</a> <span>"
6779     + escapeExpression(((helper = (helper = helpers.count || (depth0 != null ? depth0.count : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"count","hash":{},"data":data}) : helper)))
6780     + "</span>\n  </div>\n";
6781 },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
6782   var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "\n<div class=\"mkws-facet-title mkwsFacetTitle\">"
6783     + escapeExpression(((helper = (helper = helpers.caption || (depth0 != null ? depth0.caption : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"caption","hash":{},"data":data}) : helper)))
6784     + "</div>\n";
6785   stack1 = helpers.each.call(depth0, (depth0 != null ? depth0.terms : depth0), {"name":"each","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data});
6786   if (stack1 != null) { buffer += stack1; }
6787   return buffer;
6788 },"useData":true});
6789 templates['facets'] = template({"1":function(depth0,helpers,partials,data,depths) {
6790   var lambda=this.lambda, escapeExpression=this.escapeExpression;
6791   return "  <div class=\"mkws-facet mkwsFacet mkws-team-"
6792     + escapeExpression(lambda((depths[1] != null ? depths[1].team : depths[1]), depth0))
6793     + "\" data-mkws-facet=\""
6794     + escapeExpression(lambda(depth0, depth0))
6795     + "\"></div>\n";
6796 },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data,depths) {
6797   var stack1, buffer = "";
6798   stack1 = helpers.each.call(depth0, (depth0 != null ? depth0.facets : depth0), {"name":"each","hash":{},"fn":this.program(1, data, depths),"inverse":this.noop,"data":data});
6799   if (stack1 != null) { buffer += stack1; }
6800   return buffer;
6801 },"useData":true,"useDepths":true});
6802 templates['images'] = template({"1":function(depth0,helpers,partials,data,depths) {
6803   var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "  <a href=\"#\" id=\""
6804     + escapeExpression(((helper = (helper = helpers.detailLinkId || (depth0 != null ? depth0.detailLinkId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"detailLinkId","hash":{},"data":data}) : helper)))
6805     + "\" onclick=\""
6806     + escapeExpression(((helper = (helper = helpers.detailClick || (depth0 != null ? depth0.detailClick : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"detailClick","hash":{},"data":data}) : helper)))
6807     + "\">\n";
6808   stack1 = ((helpers['mkws-first'] || (depth0 && depth0['mkws-first']) || helperMissing).call(depth0, (depth0 != null ? depth0['md-thumburl'] : depth0), {"name":"mkws-first","hash":{},"fn":this.program(2, data, depths),"inverse":this.noop,"data":data}));
6809   if (stack1 != null) { buffer += stack1; }
6810   return buffer + "    <br/>\n  </a>\n";
6811 },"2":function(depth0,helpers,partials,data,depths) {
6812   var lambda=this.lambda, escapeExpression=this.escapeExpression;
6813   return "      <img src=\""
6814     + escapeExpression(lambda(depth0, depth0))
6815     + "\" alt=\""
6816     + escapeExpression(lambda((depths[1] != null ? depths[1]['md-title'] : depths[1]), depth0))
6817     + "\"/>\n";
6818 },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data,depths) {
6819   var stack1, buffer = "";
6820   stack1 = helpers.each.call(depth0, (depth0 != null ? depth0.hits : depth0), {"name":"each","hash":{},"fn":this.program(1, data, depths),"inverse":this.noop,"data":data});
6821   if (stack1 != null) { buffer += stack1; }
6822   return buffer;
6823 },"useData":true,"useDepths":true});
6824 templates['lang'] = template({"1":function(depth0,helpers,partials,data) {
6825   var stack1, buffer = "";
6826   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.selected : depth0), {"name":"if","hash":{},"fn":this.program(2, data),"inverse":this.program(4, data),"data":data});
6827   if (stack1 != null) { buffer += stack1; }
6828   stack1 = helpers.unless.call(depth0, (data && data.last), {"name":"unless","hash":{},"fn":this.program(6, data),"inverse":this.noop,"data":data});
6829   if (stack1 != null) { buffer += stack1; }
6830   return buffer;
6831 },"2":function(depth0,helpers,partials,data) {
6832   var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
6833   return "<span>"
6834     + escapeExpression(((helper = (helper = helpers.code || (depth0 != null ? depth0.code : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"code","hash":{},"data":data}) : helper)))
6835     + "</span>";
6836 },"4":function(depth0,helpers,partials,data) {
6837   var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<a href=\"";
6838   stack1 = ((helper = (helper = helpers.url || (depth0 != null ? depth0.url : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"url","hash":{},"data":data}) : helper));
6839   if (stack1 != null) { buffer += stack1; }
6840   return buffer + "\">"
6841     + escapeExpression(((helper = (helper = helpers.code || (depth0 != null ? depth0.code : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"code","hash":{},"data":data}) : helper)))
6842     + "</a>";
6843 },"6":function(depth0,helpers,partials,data) {
6844   return "    |\n";
6845   },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
6846   var stack1, buffer = "";
6847   stack1 = helpers.each.call(depth0, (depth0 != null ? depth0.languages : depth0), {"name":"each","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data});
6848   if (stack1 != null) { buffer += stack1; }
6849   return buffer + "\n";
6850 },"useData":true});
6851 templates['navi'] = template({"1":function(depth0,helpers,partials,data) {
6852   var stack1, helper, helperMissing=helpers.helperMissing, functionType="function", escapeExpression=this.escapeExpression, buffer = "  ";
6853   stack1 = ((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, (depth0 != null ? depth0.facet : depth0), {"name":"mkws-translate","hash":{},"data":data}));
6854   if (stack1 != null) { buffer += stack1; }
6855   buffer += ": <a class=\"mkws-removable mkwsRemovable\" href=\"#\" onclick=\"";
6856   stack1 = ((helper = (helper = helpers.click || (depth0 != null ? depth0.click : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"click","hash":{},"data":data}) : helper));
6857   if (stack1 != null) { buffer += stack1; }
6858   buffer += "\">"
6859     + escapeExpression(((helper = (helper = helpers.value || (depth0 != null ? depth0.value : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"value","hash":{},"data":data}) : helper)))
6860     + "</a>\n  ";
6861   stack1 = helpers.unless.call(depth0, (data && data.last), {"name":"unless","hash":{},"fn":this.program(2, data),"inverse":this.noop,"data":data});
6862   if (stack1 != null) { buffer += stack1; }
6863   return buffer + "\n";
6864 },"2":function(depth0,helpers,partials,data) {
6865   return "|";
6866   },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
6867   var stack1, buffer = "";
6868   stack1 = helpers.each.call(depth0, (depth0 != null ? depth0.filters : depth0), {"name":"each","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data});
6869   if (stack1 != null) { buffer += stack1; }
6870   return buffer + "\n";
6871 },"useData":true});
6872 templates['pager'] = template({"1":function(depth0,helpers,partials,data) {
6873   var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "    <a href=\"#\" class=\"mkws-prev mkwsPrev\" onclick=\""
6874     + escapeExpression(((helper = (helper = helpers.prevClick || (depth0 != null ? depth0.prevClick : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"prevClick","hash":{},"data":data}) : helper)))
6875     + "\">&#60;&#60; ";
6876   stack1 = ((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "Prev", {"name":"mkws-translate","hash":{},"data":data}));
6877   if (stack1 != null) { buffer += stack1; }
6878   return buffer + "</a> |\n";
6879 },"3":function(depth0,helpers,partials,data) {
6880   var stack1, helperMissing=helpers.helperMissing, buffer = "    <span class=\"mkws-prev mkwsPrev\">&#60;&#60; ";
6881   stack1 = ((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "Prev", {"name":"mkws-translate","hash":{},"data":data}));
6882   if (stack1 != null) { buffer += stack1; }
6883   return buffer + "</span> |\n";
6884 },"5":function(depth0,helpers,partials,data) {
6885   return "...";
6886   },"7":function(depth0,helpers,partials,data) {
6887   var stack1, buffer = "";
6888   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.click : depth0), {"name":"if","hash":{},"fn":this.program(8, data),"inverse":this.program(10, data),"data":data});
6889   if (stack1 != null) { buffer += stack1; }
6890   return buffer;
6891 },"8":function(depth0,helpers,partials,data) {
6892   var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
6893   return "      <a href=\"#\" onclick=\""
6894     + escapeExpression(((helper = (helper = helpers.click || (depth0 != null ? depth0.click : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"click","hash":{},"data":data}) : helper)))
6895     + "\">"
6896     + escapeExpression(((helper = (helper = helpers.number || (depth0 != null ? depth0.number : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"number","hash":{},"data":data}) : helper)))
6897     + "</a>\n";
6898 },"10":function(depth0,helpers,partials,data) {
6899   var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
6900   return "      <span class=\"mkws-current-page mkwsCurrentPage\">"
6901     + escapeExpression(((helper = (helper = helpers.number || (depth0 != null ? depth0.number : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"number","hash":{},"data":data}) : helper)))
6902     + "</span>\n";
6903 },"12":function(depth0,helpers,partials,data) {
6904   var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "    | <a href=\"#\" class=\"mkws-next mkwsNext\" onclick=\""
6905     + escapeExpression(((helper = (helper = helpers.nextClick || (depth0 != null ? depth0.nextClick : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"nextClick","hash":{},"data":data}) : helper)))
6906     + "\">";
6907   stack1 = ((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "Next", {"name":"mkws-translate","hash":{},"data":data}));
6908   if (stack1 != null) { buffer += stack1; }
6909   return buffer + " &#62;&#62;</a>\n";
6910 },"14":function(depth0,helpers,partials,data) {
6911   var stack1, helperMissing=helpers.helperMissing, buffer = "    | <span class=\"mkws-next mkwsNext\">";
6912   stack1 = ((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "Next", {"name":"mkws-translate","hash":{},"data":data}));
6913   if (stack1 != null) { buffer += stack1; }
6914   return buffer + " &#62;&#62;</span>\n";
6915 },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
6916   var stack1, helper, helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, functionType="function", buffer = "<div style=\"float: right\">\n  "
6917     + escapeExpression(((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "Displaying", {"name":"mkws-translate","hash":{},"data":data})))
6918     + ":\n  "
6919     + escapeExpression(((helper = (helper = helpers.first || (depth0 != null ? depth0.first : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"first","hash":{},"data":data}) : helper)))
6920     + " "
6921     + escapeExpression(((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "to", {"name":"mkws-translate","hash":{},"data":data})))
6922     + " "
6923     + escapeExpression(((helper = (helper = helpers.last || (depth0 != null ? depth0.last : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"last","hash":{},"data":data}) : helper)))
6924     + "\n  "
6925     + escapeExpression(((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "of", {"name":"mkws-translate","hash":{},"data":data})))
6926     + " "
6927     + escapeExpression(((helper = (helper = helpers.count || (depth0 != null ? depth0.count : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"count","hash":{},"data":data}) : helper)))
6928     + " (";
6929   stack1 = ((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "found", {"name":"mkws-translate","hash":{},"data":data}));
6930   if (stack1 != null) { buffer += stack1; }
6931   buffer += ": "
6932     + escapeExpression(((helper = (helper = helpers.found || (depth0 != null ? depth0.found : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"found","hash":{},"data":data}) : helper)))
6933     + ")\n</div>\n\n<div style=\"float: clear\">\n";
6934   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.prevClick : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.program(3, data),"data":data});
6935   if (stack1 != null) { buffer += stack1; }
6936   buffer += "\n  ";
6937   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.morePrev : depth0), {"name":"if","hash":{},"fn":this.program(5, data),"inverse":this.noop,"data":data});
6938   if (stack1 != null) { buffer += stack1; }
6939   buffer += "\n\n";
6940   stack1 = helpers.each.call(depth0, (depth0 != null ? depth0.pages : depth0), {"name":"each","hash":{},"fn":this.program(7, data),"inverse":this.noop,"data":data});
6941   if (stack1 != null) { buffer += stack1; }
6942   buffer += "\n  ";
6943   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.moreNext : depth0), {"name":"if","hash":{},"fn":this.program(5, data),"inverse":this.noop,"data":data});
6944   if (stack1 != null) { buffer += stack1; }
6945   buffer += "\n\n";
6946   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.nextClick : depth0), {"name":"if","hash":{},"fn":this.program(12, data),"inverse":this.program(14, data),"data":data});
6947   if (stack1 != null) { buffer += stack1; }
6948   return buffer + "</div>\n";
6949 },"useData":true});
6950 templates['progress'] = template({"1":function(depth0,helpers,partials,data) {
6951   return "&#x2588;";
6952   },"3":function(depth0,helpers,partials,data) {
6953   var stack1, helperMissing=helpers.helperMissing, buffer = "<span class=\"mkws-waiting mkws-waiting mkwsWaiting\">";
6954   stack1 = ((helpers['mkws-repeat'] || (depth0 && depth0['mkws-repeat']) || helperMissing).call(depth0, (depth0 != null ? depth0.waiting : depth0), {"name":"mkws-repeat","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data}));
6955   if (stack1 != null) { buffer += stack1; }
6956   return buffer + "</span>";
6957 },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
6958   var stack1, helperMissing=helpers.helperMissing, buffer = "<span class=\"mkws-done mkws-done mkwsDone\">";
6959   stack1 = ((helpers['mkws-repeat'] || (depth0 && depth0['mkws-repeat']) || helperMissing).call(depth0, (depth0 != null ? depth0.done : depth0), {"name":"mkws-repeat","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data}));
6960   if (stack1 != null) { buffer += stack1; }
6961   buffer += "</span>";
6962   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.waiting : depth0), {"name":"if","hash":{},"fn":this.program(3, data),"inverse":this.noop,"data":data});
6963   if (stack1 != null) { buffer += stack1; }
6964   return buffer;
6965 },"useData":true});
6966 templates['ranking'] = template({"1":function(depth0,helpers,partials,data) {
6967   var stack1, helper, helperMissing=helpers.helperMissing, functionType="function", escapeExpression=this.escapeExpression, buffer = "";
6968   stack1 = ((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "Sort by", {"name":"mkws-translate","hash":{},"data":data}));
6969   if (stack1 != null) { buffer += stack1; }
6970   buffer += "\n    <select class=\"mkws-sort mkwsSort mkws-team-"
6971     + escapeExpression(((helper = (helper = helpers.team || (depth0 != null ? depth0.team : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"team","hash":{},"data":data}) : helper)))
6972     + "\">\n";
6973   stack1 = helpers.each.call(depth0, (depth0 != null ? depth0.sort : depth0), {"name":"each","hash":{},"fn":this.program(2, data),"inverse":this.noop,"data":data});
6974   if (stack1 != null) { buffer += stack1; }
6975   return buffer + "    </select>";
6976 },"2":function(depth0,helpers,partials,data) {
6977   var stack1, buffer = "";
6978   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.selected : depth0), {"name":"if","hash":{},"fn":this.program(3, data),"inverse":this.program(5, data),"data":data});
6979   if (stack1 != null) { buffer += stack1; }
6980   return buffer;
6981 },"3":function(depth0,helpers,partials,data) {
6982   var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, buffer = "          <option value=\"";
6983   stack1 = ((helper = (helper = helpers.key || (depth0 != null ? depth0.key : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"key","hash":{},"data":data}) : helper));
6984   if (stack1 != null) { buffer += stack1; }
6985   buffer += "\" selected=\"selected\">";
6986   stack1 = ((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, (depth0 != null ? depth0.label : depth0), {"name":"mkws-translate","hash":{},"data":data}));
6987   if (stack1 != null) { buffer += stack1; }
6988   return buffer + "</option>\n";
6989 },"5":function(depth0,helpers,partials,data) {
6990   var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "          <option value=\""
6991     + escapeExpression(((helper = (helper = helpers.key || (depth0 != null ? depth0.key : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"key","hash":{},"data":data}) : helper)))
6992     + "\">";
6993   stack1 = ((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, (depth0 != null ? depth0.label : depth0), {"name":"mkws-translate","hash":{},"data":data}));
6994   if (stack1 != null) { buffer += stack1; }
6995   return buffer + "</option>\n";
6996 },"7":function(depth0,helpers,partials,data) {
6997   var stack1, helper, helperMissing=helpers.helperMissing, functionType="function", escapeExpression=this.escapeExpression, buffer = "    ";
6998   stack1 = ((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "and show", {"name":"mkws-translate","hash":{},"data":data}));
6999   if (stack1 != null) { buffer += stack1; }
7000   buffer += "\n    <select class=\"mkws-perpage mkwsPerpage mkws-team-"
7001     + escapeExpression(((helper = (helper = helpers.team || (depth0 != null ? depth0.team : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"team","hash":{},"data":data}) : helper)))
7002     + "\">\n";
7003   stack1 = helpers.each.call(depth0, (depth0 != null ? depth0.perPage : depth0), {"name":"each","hash":{},"fn":this.program(8, data),"inverse":this.noop,"data":data});
7004   if (stack1 != null) { buffer += stack1; }
7005   buffer += "    </select>\n    ";
7006   stack1 = ((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "per page", {"name":"mkws-translate","hash":{},"data":data}));
7007   if (stack1 != null) { buffer += stack1; }
7008   return buffer;
7009 },"8":function(depth0,helpers,partials,data) {
7010   var stack1, buffer = "";
7011   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.selected : depth0), {"name":"if","hash":{},"fn":this.program(9, data),"inverse":this.program(11, data),"data":data});
7012   if (stack1 != null) { buffer += stack1; }
7013   return buffer;
7014 },"9":function(depth0,helpers,partials,data) {
7015   var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
7016   return "          <option value=\""
7017     + escapeExpression(((helper = (helper = helpers.perPage || (depth0 != null ? depth0.perPage : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"perPage","hash":{},"data":data}) : helper)))
7018     + "\" selected=\"selected\">"
7019     + escapeExpression(((helper = (helper = helpers.perPage || (depth0 != null ? depth0.perPage : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"perPage","hash":{},"data":data}) : helper)))
7020     + "</option>\n";
7021 },"11":function(depth0,helpers,partials,data) {
7022   var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
7023   return "          <option value=\""
7024     + escapeExpression(((helper = (helper = helpers.perPage || (depth0 != null ? depth0.perPage : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"perPage","hash":{},"data":data}) : helper)))
7025     + "\">"
7026     + escapeExpression(((helper = (helper = helpers.perPage || (depth0 != null ? depth0.perPage : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"perPage","hash":{},"data":data}) : helper)))
7027     + "</option>\n";
7028 },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
7029   var stack1, buffer = "<form>";
7030   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.showSort : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data});
7031   if (stack1 != null) { buffer += stack1; }
7032   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.showPerPage : depth0), {"name":"if","hash":{},"fn":this.program(7, data),"inverse":this.noop,"data":data});
7033   if (stack1 != null) { buffer += stack1; }
7034   return buffer + "</form>\n\n";
7035 },"useData":true});
7036 templates['records'] = template({"1":function(depth0,helpers,partials,data) {
7037   var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "  <div class=\""
7038     + escapeExpression(((helper = (helper = helpers.containerClass || (depth0 != null ? depth0.containerClass : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"containerClass","hash":{},"data":data}) : helper)))
7039     + "\">\n";
7040   stack1 = this.invokePartial(partials.summary, '    ', 'summary', depth0, undefined, helpers, partials, data);
7041   if (stack1 != null) { buffer += stack1; }
7042   return buffer + "  </div>\n";
7043 },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
7044   var stack1, buffer = "";
7045   stack1 = helpers.each.call(depth0, (depth0 != null ? depth0.hits : depth0), {"name":"each","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data});
7046   if (stack1 != null) { buffer += stack1; }
7047   return buffer;
7048 },"usePartial":true,"useData":true});
7049 templates['reference'] = template({"1":function(depth0,helpers,partials,data) {
7050   var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
7051   return "<b>"
7052     + escapeExpression(((helper = (helper = helpers['md-title-remainder'] || (depth0 != null ? depth0['md-title-remainder'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"md-title-remainder","hash":{},"data":data}) : helper)))
7053     + "</b>\n";
7054 },"3":function(depth0,helpers,partials,data) {
7055   var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
7056   return "<i>"
7057     + escapeExpression(((helper = (helper = helpers['md-title-responsibility'] || (depth0 != null ? depth0['md-title-responsibility'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"md-title-responsibility","hash":{},"data":data}) : helper)))
7058     + "</i>\n";
7059 },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
7060   var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<img src=\""
7061     + escapeExpression(((helper = (helper = helpers['md-thumburl'] || (depth0 != null ? depth0['md-thumburl'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"md-thumburl","hash":{},"data":data}) : helper)))
7062     + "\" alt=\""
7063     + escapeExpression(((helper = (helper = helpers['md-title'] || (depth0 != null ? depth0['md-title'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"md-title","hash":{},"data":data}) : helper)))
7064     + "\">\n<h1><a href=\""
7065     + escapeExpression(((helper = (helper = helpers['md-electronic-url'] || (depth0 != null ? depth0['md-electronic-url'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"md-electronic-url","hash":{},"data":data}) : helper)))
7066     + "\">"
7067     + escapeExpression(((helper = (helper = helpers['md-title'] || (depth0 != null ? depth0['md-title'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"md-title","hash":{},"data":data}) : helper)))
7068     + "</a></h1>\n";
7069   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0['md-title-remainder'] : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data});
7070   if (stack1 != null) { buffer += stack1; }
7071   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0['md-title-responsibility'] : depth0), {"name":"if","hash":{},"fn":this.program(3, data),"inverse":this.noop,"data":data});
7072   if (stack1 != null) { buffer += stack1; }
7073   stack1 = ((helpers['mkws-paragraphs'] || (depth0 && depth0['mkws-paragraphs']) || helperMissing).call(depth0, (depth0 != null ? depth0['md-description'] : depth0), (depth0 != null ? depth0.paragraphs : depth0), (depth0 != null ? depth0.sentences : depth0), {"name":"mkws-paragraphs","hash":{},"data":data}));
7074   if (stack1 != null) { buffer += stack1; }
7075   return buffer + "\n<p class=\"mkws-credit mkwsCredit\">Wikipedia</p>\n";
7076 },"useData":true});
7077 templates['results'] = template({"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
7078   var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
7079   return "<table width=\"100%\" border=\"0\" cellpadding=\"6\" cellspacing=\"0\">\n  <tr>\n    <td class=\"mkws-facets-container-wide mkws-team-"
7080     + escapeExpression(((helper = (helper = helpers.team || (depth0 != null ? depth0.team : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"team","hash":{},"data":data}) : helper)))
7081     + "\" width=\"250\" valign=\"top\">\n      <div class=\"mkws-facets mkwsTermlists mkws-team-"
7082     + escapeExpression(((helper = (helper = helpers.team || (depth0 != null ? depth0.team : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"team","hash":{},"data":data}) : helper)))
7083     + "\"></div>\n    </td>\n    <td class=\"mkws-motd-container mkwsMOTDContainer mkws-team-"
7084     + escapeExpression(((helper = (helper = helpers.team || (depth0 != null ? depth0.team : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"team","hash":{},"data":data}) : helper)))
7085     + "\" valign=\"top\">\n      <div class=\"mkws-ranking mkwsRanking mkws-team-"
7086     + escapeExpression(((helper = (helper = helpers.team || (depth0 != null ? depth0.team : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"team","hash":{},"data":data}) : helper)))
7087     + "\"></div>\n      <div class=\"mkws-pager mkwsPager mkws-team-"
7088     + escapeExpression(((helper = (helper = helpers.team || (depth0 != null ? depth0.team : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"team","hash":{},"data":data}) : helper)))
7089     + "\"></div>\n      <div class=\"mkws-navi mkwsNavi mkws-team-"
7090     + escapeExpression(((helper = (helper = helpers.team || (depth0 != null ? depth0.team : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"team","hash":{},"data":data}) : helper)))
7091     + "\"></div>\n      <div class=\"mkws-records mkwsRecords mkws-team-"
7092     + escapeExpression(((helper = (helper = helpers.team || (depth0 != null ? depth0.team : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"team","hash":{},"data":data}) : helper)))
7093     + "\"></div>\n    </td>\n  </tr>\n  <tr>\n    <td colspan=\"2\">\n      <div class=\"mkws-facets-container-narrow mkws-team-"
7094     + escapeExpression(((helper = (helper = helpers.team || (depth0 != null ? depth0.team : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"team","hash":{},"data":data}) : helper)))
7095     + "\"></div>\n    </td>\n  </tr>\n</table>\n\n";
7096 },"useData":true});
7097 templates['search'] = template({"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
7098   var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "<form name=\"mkws-search-form\" class=\"mkws-search-form mkws-team-"
7099     + escapeExpression(((helper = (helper = helpers.team || (depth0 != null ? depth0.team : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"team","hash":{},"data":data}) : helper)))
7100     + "\" action=\"\">\n  <input class=\"mkws-query mkws-query mkwsQuery mkws-team-"
7101     + escapeExpression(((helper = (helper = helpers.team || (depth0 != null ? depth0.team : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"team","hash":{},"data":data}) : helper)))
7102     + "\" type=\"text\"/>\n  <input class=\"mkws-button mkws-button mkwsButton mkws-team-"
7103     + escapeExpression(((helper = (helper = helpers.team || (depth0 != null ? depth0.team : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"team","hash":{},"data":data}) : helper)))
7104     + "\" type=\"submit\" value=\"";
7105   stack1 = ((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "Search", {"name":"mkws-translate","hash":{},"data":data}));
7106   if (stack1 != null) { buffer += stack1; }
7107   return buffer + "\"/>\n</form>\n\n";
7108 },"useData":true});
7109 templates['stat'] = template({"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
7110   var stack1, helper, helperMissing=helpers.helperMissing, functionType="function", escapeExpression=this.escapeExpression, buffer = " -- <span class=\"mkws-client-count mkwsClientCount\">";
7111   stack1 = ((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "Active clients", {"name":"mkws-translate","hash":{},"data":data}));
7112   if (stack1 != null) { buffer += stack1; }
7113   buffer += " : "
7114     + escapeExpression(((helper = (helper = helpers.activeclients || (depth0 != null ? depth0.activeclients : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"activeclients","hash":{},"data":data}) : helper)))
7115     + "/"
7116     + escapeExpression(((helper = (helper = helpers.clients || (depth0 != null ? depth0.clients : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"clients","hash":{},"data":data}) : helper)))
7117     + "</span> -- ";
7118   stack1 = ((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "Retrieved records", {"name":"mkws-translate","hash":{},"data":data}));
7119   if (stack1 != null) { buffer += stack1; }
7120   return buffer + " : "
7121     + escapeExpression(((helper = (helper = helpers.records || (depth0 != null ? depth0.records : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"records","hash":{},"data":data}) : helper)))
7122     + "/"
7123     + escapeExpression(((helper = (helper = helpers.hits || (depth0 != null ? depth0.hits : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"hits","hash":{},"data":data}) : helper)))
7124     + "\n";
7125 },"useData":true});
7126 templates['summary'] = template({"1":function(depth0,helpers,partials,data) {
7127   var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, lambda=this.lambda;
7128   return "  <a class=\"mkws-field-thumb\" href=\"#\" onclick=\""
7129     + escapeExpression(((helper = (helper = helpers.detailClick || (depth0 != null ? depth0.detailClick : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"detailClick","hash":{},"data":data}) : helper)))
7130     + "\">\n    <img src=\""
7131     + escapeExpression(lambda(((stack1 = (depth0 != null ? depth0['md-thumburl'] : depth0)) != null ? stack1['0'] : stack1), depth0))
7132     + "\"/>\n  </a>\n";
7133 },"3":function(depth0,helpers,partials,data) {
7134   var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
7135   return "    <span class=\"mkws-field-title-remainder\">"
7136     + escapeExpression(((helper = (helper = helpers['md-title-remainder'] || (depth0 != null ? depth0['md-title-remainder'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"md-title-remainder","hash":{},"data":data}) : helper)))
7137     + "</span>\n";
7138 },"5":function(depth0,helpers,partials,data) {
7139   var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
7140   return "    <span class=\"mkws-field-author\">"
7141     + escapeExpression(((helper = (helper = helpers['md-author'] || (depth0 != null ? depth0['md-author'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"md-author","hash":{},"data":data}) : helper)))
7142     + "</span>\n";
7143 },"7":function(depth0,helpers,partials,data) {
7144   var stack1, buffer = "";
7145   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0['md-title-responsibility'] : depth0), {"name":"if","hash":{},"fn":this.program(8, data),"inverse":this.noop,"data":data});
7146   if (stack1 != null) { buffer += stack1; }
7147   return buffer;
7148 },"8":function(depth0,helpers,partials,data) {
7149   var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
7150   return "      <span class=\"mkws-field-author\">"
7151     + escapeExpression(((helper = (helper = helpers['md-title-responsibility'] || (depth0 != null ? depth0['md-title-responsibility'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"md-title-responsibility","hash":{},"data":data}) : helper)))
7152     + "</span>\n";
7153 },"10":function(depth0,helpers,partials,data) {
7154   var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
7155   return "    <div class=\"mkws-field-description\">"
7156     + escapeExpression(((helper = (helper = helpers['md-description'] || (depth0 != null ? depth0['md-description'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"md-description","hash":{},"data":data}) : helper)))
7157     + "</div>\n";
7158 },"12":function(depth0,helpers,partials,data) {
7159   var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
7160   return "    <span class=\"mkws-field-date\">"
7161     + escapeExpression(((helper = (helper = helpers['md-date'] || (depth0 != null ? depth0['md-date'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"md-date","hash":{},"data":data}) : helper)))
7162     + "</span>\n";
7163 },"14":function(depth0,helpers,partials,data) {
7164   var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, buffer = "  ";
7165   stack1 = ((helper = (helper = helpers.renderedDetails || (depth0 != null ? depth0.renderedDetails : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"renderedDetails","hash":{},"data":data}) : helper));
7166   if (stack1 != null) { buffer += stack1; }
7167   return buffer + "\n";
7168 },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
7169   var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "";
7170   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0['md-thumburl'] : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data});
7171   if (stack1 != null) { buffer += stack1; }
7172   buffer += "<div class=\"mkws-field-data\">\n  <span class=\"mkws-field-title\">\n  <a href=\"#\" id=\""
7173     + escapeExpression(((helper = (helper = helpers.detailLinkId || (depth0 != null ? depth0.detailLinkId : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"detailLinkId","hash":{},"data":data}) : helper)))
7174     + "\" onclick=\""
7175     + escapeExpression(((helper = (helper = helpers.detailClick || (depth0 != null ? depth0.detailClick : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"detailClick","hash":{},"data":data}) : helper)))
7176     + "\">\n    "
7177     + escapeExpression(((helper = (helper = helpers['md-title'] || (depth0 != null ? depth0['md-title'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"md-title","hash":{},"data":data}) : helper)))
7178     + "\n  </a>\n  </span>\n";
7179   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0['md-title-remainder'] : depth0), {"name":"if","hash":{},"fn":this.program(3, data),"inverse":this.noop,"data":data});
7180   if (stack1 != null) { buffer += stack1; }
7181   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0['md-author'] : depth0), {"name":"if","hash":{},"fn":this.program(5, data),"inverse":this.program(7, data),"data":data});
7182   if (stack1 != null) { buffer += stack1; }
7183   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0['md-description'] : depth0), {"name":"if","hash":{},"fn":this.program(10, data),"inverse":this.noop,"data":data});
7184   if (stack1 != null) { buffer += stack1; }
7185   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0['md-date'] : depth0), {"name":"if","hash":{},"fn":this.program(12, data),"inverse":this.noop,"data":data});
7186   if (stack1 != null) { buffer += stack1; }
7187   buffer += "</div>\n";
7188   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.renderedDetails : depth0), {"name":"if","hash":{},"fn":this.program(14, data),"inverse":this.noop,"data":data});
7189   if (stack1 != null) { buffer += stack1; }
7190   return buffer;
7191 },"useData":true});
7192 templates['switch'] = template({"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
7193   var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, buffer = "<a href=\"#\" onclick=\"";
7194   stack1 = ((helper = (helper = helpers.recordClick || (depth0 != null ? depth0.recordClick : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"recordClick","hash":{},"data":data}) : helper));
7195   if (stack1 != null) { buffer += stack1; }
7196   buffer += "\">";
7197   stack1 = ((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "Records", {"name":"mkws-translate","hash":{},"data":data}));
7198   if (stack1 != null) { buffer += stack1; }
7199   buffer += "</a>\n<span>|</span>\n<a href=\"#\" onclick=\"";
7200   stack1 = ((helper = (helper = helpers.targetClick || (depth0 != null ? depth0.targetClick : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"targetClick","hash":{},"data":data}) : helper));
7201   if (stack1 != null) { buffer += stack1; }
7202   buffer += "\">";
7203   stack1 = ((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "Targets", {"name":"mkws-translate","hash":{},"data":data}));
7204   if (stack1 != null) { buffer += stack1; }
7205   return buffer + "</a>\n";
7206 },"useData":true});
7207 templates['targets'] = template({"1":function(depth0,helpers,partials,data) {
7208   var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "    <tr>\n      <td>";
7209   stack1 = ((helper = (helper = helpers.id || (depth0 != null ? depth0.id : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"id","hash":{},"data":data}) : helper));
7210   if (stack1 != null) { buffer += stack1; }
7211   buffer += "</td>\n      <td>"
7212     + escapeExpression(((helper = (helper = helpers.hits || (depth0 != null ? depth0.hits : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"hits","hash":{},"data":data}) : helper)))
7213     + "</td>\n      <td>\n";
7214   stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.message : depth0), {"name":"if","hash":{},"fn":this.program(2, data),"inverse":this.noop,"data":data});
7215   if (stack1 != null) { buffer += stack1; }
7216   return buffer + "      </td>\n      <td>"
7217     + escapeExpression(((helper = (helper = helpers.records || (depth0 != null ? depth0.records : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"records","hash":{},"data":data}) : helper)))
7218     + "</td>\n      <td>"
7219     + escapeExpression(((helper = (helper = helpers.state || (depth0 != null ? depth0.state : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"state","hash":{},"data":data}) : helper)))
7220     + "</td>\n    </tr>\n";
7221 },"2":function(depth0,helpers,partials,data) {
7222   var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression;
7223   return "         "
7224     + escapeExpression(((helper = (helper = helpers.diagnostic || (depth0 != null ? depth0.diagnostic : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"diagnostic","hash":{},"data":data}) : helper)))
7225     + " ("
7226     + escapeExpression(((helper = (helper = helpers.message || (depth0 != null ? depth0.message : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"message","hash":{},"data":data}) : helper)))
7227     + ")\n";
7228 },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) {
7229   var stack1, helperMissing=helpers.helperMissing, buffer = "<table>\n  <thead>\n    <tr>\n      <td>";
7230   stack1 = ((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "Target ID", {"name":"mkws-translate","hash":{},"data":data}));
7231   if (stack1 != null) { buffer += stack1; }
7232   buffer += "</td>\n      <td>";
7233   stack1 = ((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "Hits", {"name":"mkws-translate","hash":{},"data":data}));
7234   if (stack1 != null) { buffer += stack1; }
7235   buffer += "</td>\n      <td>";
7236   stack1 = ((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "Diags", {"name":"mkws-translate","hash":{},"data":data}));
7237   if (stack1 != null) { buffer += stack1; }
7238   buffer += "</td>\n      <td>";
7239   stack1 = ((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "Records", {"name":"mkws-translate","hash":{},"data":data}));
7240   if (stack1 != null) { buffer += stack1; }
7241   buffer += "</td>\n      <td>";
7242   stack1 = ((helpers['mkws-translate'] || (depth0 && depth0['mkws-translate']) || helperMissing).call(depth0, "State", {"name":"mkws-translate","hash":{},"data":data}));
7243   if (stack1 != null) { buffer += stack1; }
7244   buffer += "</td>\n      </td>\n    </tr>\n  </thead>\n  <tbody>\n";
7245   stack1 = helpers.each.call(depth0, (depth0 != null ? depth0.data : depth0), {"name":"each","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data});
7246   if (stack1 != null) { buffer += stack1; }
7247   return buffer + "  </tbody>\n</table>\n";
7248 },"useData":true});
7249 })();/* generic function to open results in a popup window
7250  *
7251  */
7252
7253 //"use strict";
7254 // $(document).ready(function () {
7255 mkws.registerWidgetType('popup', function() {
7256     var $ = mkws.$;
7257     var debug = this.log;
7258     debug("init popup window");
7259
7260     var popup_window = $(this.node);
7261     // var popup_window = $(".mkws-popup mkwsPopup"); // $(document).ready()
7262     if (!popup_window) {
7263         debug("no popup found, skip...");
7264         return;
7265     } else {
7266         debug("number of popup windows found: " + popup_window.length);
7267     }
7268
7269     if (!$.ui) {
7270         alert("Error: jquery-ui.js is missing, did you include it after jQuery core in the HTML file?");
7271         return;
7272     }
7273
7274     // more than one widget on a page are possible
7275     popup_window.each(function(i) {
7276         var that = $(this);
7277
7278         // all atributes are strings, convert them to integers here
7279         var width = parseInt(that.attr("popup_width") || "800");
7280         var height = parseInt(that.attr("popup_height") || "600");
7281         var autoOpen = parseInt(that.attr("popup_autoOpen") || "0");
7282         var modal = parseInt(that.attr("popup_modal") || "0");
7283
7284         debug("Popup parameters: width: " + width + ", height: " + height + ", autoOpen: " + autoOpen);
7285         that.dialog({
7286             closeOnEscape: true,
7287             autoOpen: autoOpen,
7288             height: height,
7289             width: width,
7290             modal: modal ? true : false,
7291             resizable: true,
7292             buttons: {
7293                 Cancel: function() {
7294                     that.dialog("close");
7295                 }
7296             },
7297             close: function() {}
7298         });
7299
7300         // open at search query submit: "input.mkws-button mkwsButton"
7301         var id_botton = that.attr("popup_button");
7302         if (id_botton) {
7303             $(id_botton).button().click(function() {
7304                 that.dialog("open");
7305             });
7306         }
7307     });
7308 });